Skip to content

Outputs & Decks API

API endpoints for managing Outputs and Decks - the system for tracking user-generated content across the Emerge platform.

Key Concepts

Output

A global parent record for ALL generated content (images, videos, etc.).

  • Tracks the lifecycle of a generation: pending → processing → completed/failed
  • Links to the source collection, job, and storage (flat_file)
  • Supports custodial ownership for users who haven't signed up yet

Deck

Groups related outputs over time, tied to a specific collection.

  • Think of it like an "album" of generations from a collection
  • Auto-created when a user generates their first output from a collection
  • Supports multiple decks per collection (different generation sessions)

Custodial Ownership

Content can be held "in custody" for social users (Farcaster, Twitter, etc.) who haven't created a full account yet. When they sign up, custody is transferred.


Response Format

All endpoints return responses in this format:

json
{
  "data": { /* response data */ },
  "error": null | "Error message"
}

Authentication

All endpoints require the user_id header:

user_id: <uuid>

Output Endpoints

Create Pending Output

Creates a new output record in pending status when a generation job starts.

POST /outputs

Request Body:

json
{
  "collection_id": "uuid",           // Required: The collection this output belongs to
  "job_id": "uuid",                  // Optional: Link to job record
  "source": "miniapp",               // Optional: Where the generation originated
  "input_metadata": { ... },         // Optional: Input parameters for the generation
  "social_org": "farcaster",         // Optional: For custodial outputs
  "social_identifier": "username",   // Optional: Platform-specific identifier
  "deck_id": "uuid",                 // Optional: Specific deck to add to
  "auto_create_deck": true           // Optional: Auto-create deck if none exists (default: true)
}

Source values:

  • direct_api - API call
  • ai_terminal - AI Terminal
  • miniapp - Farcaster miniapp
  • studio_component - Studio component
  • studio_workflow - Studio workflow
  • load_test - Load testing
  • unknown - Unknown source

Response (201):

json
{
  "data": {
    "id": "uuid",
    "collection_id": "uuid",
    "deck_id": "uuid",
    "job_id": "uuid",
    "status": "pending",
    "source": "miniapp",
    "is_custodial": true,
    "custodied_for": "uuid",
    "created_at": "2024-01-10T..."
  },
  "error": null
}

Complete Output

Marks an output as completed with the generated URL.

PATCH /outputs/:id/complete

Request Body:

json
{
  "url": "https://cdn.example.com/file.mp4",  // Required: URL of the generated content
  "mime_type": "video/mp4",                    // Optional: MIME type
  "thumbnail_url": "https://...",              // Optional: Thumbnail URL
  "flat_file_id": 12345,                       // Optional: Link to flat_file record
  "output_metadata": { ... }                   // Optional: Generation output data
}

Response (200):

json
{
  "data": {
    "id": "uuid",
    "status": "completed",
    "url": "https://cdn.example.com/file.mp4",
    "mime_type": "video/mp4",
    "completed_at": "2024-01-10T..."
  },
  "error": null
}

Fail Output

Marks an output as failed with an error message.

PATCH /outputs/:id/fail

Request Body:

json
{
  "error_message": "Generation failed: timeout"
}

Response (200):

json
{
  "data": {
    "id": "uuid",
    "status": "failed",
    "error_message": "Generation failed: timeout"
  },
  "error": null
}

Hide Output (Soft Delete)

Hides an output from user-facing views.

DELETE /outputs/:id

Response (200):

json
{
  "data": {
    "id": "uuid",
    "status": "hidden"
  },
  "error": null
}

Get Output

Retrieves a single output by ID.

GET /outputs/:id

Response (200):

json
{
  "data": {
    "id": "uuid",
    "url": "https://...",
    "mime_type": "video/mp4",
    "status": "completed",
    "collection_id": "uuid",
    "deck_id": "uuid",
    "deck": {
      "id": "uuid",
      "name": "My Deck"
    },
    "collection": {
      "id": "uuid",
      "title": "Veo Video Generator"
    },
    "created_at": "...",
    "completed_at": "..."
  },
  "error": null
}

Move Output to Deck

Moves an output to a different deck (or removes from deck).

PATCH /outputs/:id/deck

Request Body:

json
{
  "deck_id": "uuid"  // null to remove from deck
}

Response (200):

json
{
  "data": {
    "id": "uuid",
    "deck_id": "uuid"
  },
  "error": null
}

List Collection Outputs

Lists outputs for a collection, optionally filtered by deck or user.

GET /collections/:collectionId/outputs

Query Parameters:

ParameterTypeDescription
deck_iduuidFilter by deck
statusstringFilter by status (pending, completed, failed)
social_orgstringFilter by social platform (custodial)
social_identifierstringFilter by social identifier
limitnumberMax results (default: 50)
offsetnumberPagination offset (default: 0)

Response (200):

json
{
  "data": [
    {
      "id": "uuid",
      "url": "https://...",
      "status": "completed",
      "deck": { "id": "uuid", "name": "My Deck" }
    }
  ],
  "error": null
}

Get Collection Output Stats

Returns statistics about outputs for a collection.

GET /collections/:collectionId/outputs/stats

Response (200):

json
{
  "data": {
    "total": 150,
    "byStatus": {
      "completed": 120,
      "pending": 5,
      "failed": 20,
      "hidden": 5
    }
  },
  "error": null
}

Develop Output (Video Transformation)

The "develop" feature allows transforming an existing output using a global collection (a reusable workflow). For example, turning an image into a video.

Develop Output

Creates a new output derived from an existing output using a global collection's workflow.

POST /outputs/:id/develop

Request Body:

json
{
  "collection_id": "uuid",           // Required: The global collection to use
  "variables": {                     // Optional: Additional variables
    "aspect_ratio": "16:9",
    "duration": "5s"
  }
}

Response (202 - Accepted):

json
{
  "data": {
    "job_id": "uuid",
    "output_id": "uuid",
    "status": "pending",
    "develop_collection": {
      "id": "uuid",
      "title": "Image to Video",
      "input_type": "image",
      "output_type": "video"
    },
    "source_output": {
      "id": "uuid",
      "url": "https://...",
      "mime_type": "image/png"
    }
  },
  "error": null
}

Notes:

  • The new output is placed in the same deck as the source output
  • The source output must be in completed status
  • The global collection must have is_global: true
  • Input type must match (e.g., image collection for image source)

List Global Collections

Lists available global collections for developing outputs.

GET /outputs/develop/collections

Query Parameters:

ParameterTypeDescription
input_typestringFilter by input type (image, video, text)

Response (200):

json
{
  "data": [
    {
      "id": "uuid",
      "title": "Image to Video",
      "description": "Transform images into videos using Veo",
      "input_type": "image",
      "output_type": "video",
      "cover_image_url": "https://..."
    },
    {
      "id": "uuid",
      "title": "Upscale Image",
      "description": "4x upscale using Real-ESRGAN",
      "input_type": "image",
      "output_type": "image",
      "cover_image_url": "https://..."
    }
  ],
  "error": null
}

Deck Endpoints

Create Deck

Creates a new deck for a collection.

POST /decks

Request Body:

json
{
  "collection_id": "uuid",           // Required
  "name": "My Video Collection",     // Optional
  "description": "Videos from...",   // Optional
  "social_org": "farcaster",         // Optional: For custodial decks
  "social_identifier": "username"    // Optional
}

Response (201):

json
{
  "data": {
    "id": "uuid",
    "collection_id": "uuid",
    "name": "My Video Collection",
    "status": "active",
    "output_count": 0,
    "created_at": "..."
  },
  "error": null
}

Get Deck

Retrieves a deck with its outputs.

GET /decks/:id

Response (200):

json
{
  "data": {
    "id": "uuid",
    "name": "My Deck",
    "status": "active",
    "output_count": 5,
    "collection": {
      "id": "uuid",
      "title": "Veo Generator",
      "cover_image_url": "https://..."
    },
    "outputs": [
      {
        "id": "uuid",
        "url": "https://...",
        "status": "completed",
        "mime_type": "video/mp4",
        "position": 1
      }
    ]
  },
  "error": null
}

Update Deck

Updates deck properties.

PATCH /decks/:id

Request Body:

json
{
  "name": "Updated Name",
  "description": "New description",
  "cover_output_id": "uuid",
  "status": "published"
}

Status values:

  • active - Normal deck, can receive new outputs
  • archived - Hidden from default views
  • published - Shared/published deck
  • locked - Cannot add new outputs

Response (200):

json
{
  "data": {
    "id": "uuid",
    "name": "Updated Name",
    "status": "published"
  },
  "error": null
}

Archive Deck (Soft Delete)

Archives a deck, hiding it from default views.

DELETE /decks/:id

Response (200):

json
{
  "data": {
    "id": "uuid",
    "status": "archived"
  },
  "error": null
}

Publish Deck

Marks a deck as published/shareable.

POST /decks/:id/publish

Response (200):

json
{
  "data": {
    "id": "uuid",
    "status": "published",
    "published_at": "2024-01-10T..."
  },
  "error": null
}

Lock Deck

Locks a deck to prevent new outputs from being added.

POST /decks/:id/lock

Response (200):

json
{
  "data": {
    "id": "uuid",
    "status": "locked"
  },
  "error": null
}

Get Deck Stats

Returns statistics about outputs in a deck.

GET /decks/:id/stats

Response (200):

json
{
  "data": {
    "byStatus": {
      "completed": 10,
      "pending": 2,
      "failed": 1
    }
  },
  "error": null
}

List Collection Decks

Lists decks for a specific collection.

GET /collections/:collectionId/decks

Query Parameters:

ParameterTypeDescription
social_orgstringFilter by social platform
social_identifierstringFilter by social identifier

Response (200):

json
{
  "data": [
    {
      "id": "uuid",
      "name": "My Deck",
      "status": "active",
      "output_count": 5,
      "created_at": "..."
    }
  ],
  "error": null
}

List User Decks

Lists all decks for the current user across all collections.

GET /decks

Query Parameters:

ParameterTypeDescription
social_orgstringFilter by social platform (custodial)
social_identifierstringFilter by social identifier

Response (200):

json
{
  "data": [
    {
      "id": "uuid",
      "name": "My Deck",
      "status": "active",
      "output_count": 5,
      "collection": {
        "id": "uuid",
        "title": "Veo Generator"
      }
    }
  ],
  "error": null
}

Video Streaming (Mux Integration)

Videos uploaded through the platform are automatically processed by Mux for adaptive streaming. The flat_file record is updated with:

  • mux_asset_id: Mux's internal asset identifier
  • mux_playback_id: The ID used for streaming playback

Displaying Videos

When displaying videos, check for mux_playback_id:

typescript
// If mux_playback_id exists, use MuxPlayer
if (flatFile.mux_playback_id) {
  return (
    <MuxPlayer
      playbackId={flatFile.mux_playback_id}
      streamType="on-demand"
    />
  );
}

// Otherwise fall back to native video
return <video src={flatFile.url} controls />;

Forensics/Debug View

The forensics API returns flat_files with Mux data:

GET /api/jobs/:jobId/forensics

Response includes _flat_files array with Mux IDs:

json
{
  "job": {
    "payload": {
      "_flat_files": [
        {
          "id": 12345,
          "url": "generations/...",
          "mime_type": "video/mp4",
          "mux_asset_id": "1L3400tF301xX5bFw1vl9WOG71QZz02xy02hVFBU2ThZ7mE",
          "mux_playback_id": "7iwyZezQo4fjZoYPOMV9NWe1vuXMg6fE5lBKqQvnXOE"
        }
      ]
    }
  }
}

Error Codes

StatusMeaning
400Bad Request - Invalid parameters
401Unauthorized - Missing user_id header
404Not Found - Resource doesn't exist
500Internal Server Error

Architecture Diagrams

Data Model

Output Lifecycle

Develop Output Flow

Custodial Ownership Model

Video Display Decision Tree


Data Flow Example

User generates content in miniapp:

  1. Create pending output:

    POST /outputs
    { collection_id, source: "miniapp", social_org: "farcaster", social_identifier: "vitalik" }
    → Creates output + auto-creates deck
  2. Generation completes:

    PATCH /outputs/:id/complete
    { url, flat_file_id, mime_type: "image/png" }
  3. User wants to make it a video:

    POST /outputs/:id/develop
    { collection_id: "image-to-video-global-collection" }
    → Creates new output in same deck, starts job
  4. Video completes, Mux processes it:

    • flat_file updated with mux_playback_id
    • Output marked completed
  5. User views their deck:

    GET /decks/:id
    → Returns deck with all outputs (image + video)

Released under the MIT License.