Files
vfxreview/EXT_API_REFERENCE.md
twotalesanimation 243fbbce7a
Deploy / deploy (push) Successful in 2m45s
API Update
2026-07-21 09:53:12 +02:00

13 KiB

VFXReview External API Reference

Base URL: https://review.twotalesvfx.com

All requests require an Authorization header. Two formats are accepted:

Authorization: Bearer <API_SECRET_KEY>
X-Api-Key: <API_SECRET_KEY>

Endpoints Overview

Method Path Description
GET /api/ext/projects List all projects with showIds
GET /api/ext/shots/lookup Look up a shot by code — primary pipeline endpoint
GET /api/ext/projects/{projectCode}/episodes List episodes for a project
GET /api/ext/projects/{projectCode}/shots List shots for a project by code
GET /api/ext/shots List shots by database project ID
GET /api/ext/shots/{shotId} Get a single shot by DB id or shot code
POST /api/ext/shots Create a new shot
PATCH /api/ext/shots/{shotId} Update shot fields (e.g. increment version)

Shot Status Values

Value Description
WAITING Not yet started
IN_PROGRESS Currently being worked on
IN_REVIEW Submitted for review
REVISIONS Changes requested
COMPLETE Approved and complete

Shot Priority Values

Value Description
LOW Low priority
NORMAL Default
HIGH High priority
URGENT Urgent

Shot Code Format

{showId}_{episode}_{scene}_{shotNumber}

e.g.  UNG_106_010_020
      ^^^  ^^^  ^^^  ^^^
      |    |    |    shot number (zero-padded)
      |    |    scene
      |    episode
      show ID

1. List Projects

GET /api/ext/projects

Returns all projects with their showId, code, and metadata. Useful for populating project selectors in pipeline tools or resolving a showId → projectCode mapping.

Query Parameters

Parameter Required Default Description
status No ACTIVE ACTIVE, ARCHIVED, or ALL

Response 200 OK

{
  "projects": [
    {
      "id": "cmp6l5mzq0001ua0gz07bk72f",
      "name": "Ungo Season 1",
      "code": "UNG_S1",
      "showId": "UNG",
      "projectType": "EPISODIC",
      "status": "ACTIVE",
      "startDate": "2026-01-01T00:00:00.000Z",
      "dueDate": "2026-12-01T00:00:00.000Z",
      "_count": { "shots": 312 }
    }
  ],
  "total": 1
}

Project Type Values

Value Description
STANDARD Non-episodic project
EPISODIC Series with episode numbers

Project Status Values

Value Description
ACTIVE Currently in production
ARCHIVED Completed or archived

2. Look Up Shot by Code

Primary endpoint used by pipeline tools (After Effects, Nuke, etc.)

GET /api/ext/shots/lookup?shotCode={shotCode}&projectCode={projectCode}

Query Parameters

Parameter Required Description
shotCode Yes Human-readable shot code, e.g. UNG_106_010_020
projectCode Recommended Project code, e.g. UNG_S1 — disambiguates if same shot code appears in multiple projects

Response 200 OK

{
  "shot": {
    "id": "clxxxxxxxxxxxxxx",
    "shotCode": "UNG_106_010_020",
    "scene": "010",
    "episode": "106",
    "sequence": "010",
    "shotNumber": 20,
    "description": "Hero establishing wide",
    "notes": "Keep sky practical",
    "status": "IN_PROGRESS",
    "priority": "NORMAL",
    "frameStart": 1001,
    "frameEnd": 1120,
    "fps": 24,
    "dueDate": "2026-08-01T00:00:00.000Z",
    "thumbnailUrl": "/api/files/thumb_abc123",
    "createdAt": "2026-06-01T10:00:00.000Z",
    "updatedAt": "2026-07-15T14:30:00.000Z",

    "shotVersion": "v003",
    "exrOutput": "UNG_106_010_020_cmp_TT_v003",

    "sourceClip": "A106_C020_0601AB",
    "timecodeStart": "01:00:10:00",
    "timecodeEnd": "01:00:15:00",
    "clipDuration": "00:00:05:00",
    "seqTimecodeStart": "00:59:49:12",
    "seqTimecodeEnd": "00:59:55:00",

    "project": {
      "id": "cmp6l5mzq0001ua0gz07bk72f",
      "name": "Ungo Season 1",
      "code": "UNG_S1",
      "showId": "UNG"
    },
    "artist": {
      "id": "clxxxxxxxxxxxxxx",
      "name": "Jane Smith",
      "email": "jane@studio.com"
    },
    "tasks": [
      {
        "id": "clxxxxxxxxxxxxxx",
        "title": "Comp",
        "type": "COMP",
        "status": "IN_PROGRESS"
      }
    ],
    "versions": [
      {
        "id": "clxxxxxxxxxxxxxx",
        "versionNumber": 3,
        "approvalStatus": "PENDING",
        "reviewStatus": "PENDING",
        "fileUrl": "/api/files/vid_abc123",
        "thumbnailUrl": "/api/files/thumb_abc123",
        "createdAt": "2026-07-15T14:30:00.000Z"
      }
    ]
  }
}

Pipeline-Specific Fields

Field Type Description
shotVersion string Current version string, e.g. v003. Used for output naming.
exrOutput string Base filename for EXR renders, e.g. UNG_106_010_020_cmp_TT_v003
seqTimecodeStart string Shot in-point in the locked picture sequence (HH:MM:SS:FF)
seqTimecodeEnd string Shot out-point in the locked picture sequence (HH:MM:SS:FF)
sourceClip string Original camera roll/clip name from the EDL
timecodeStart string Source clip timecode in (HH:MM:SS:FF)
timecodeEnd string Source clip timecode out (HH:MM:SS:FF)
clipDuration string Clip duration (HH:MM:SS:FF)

3. List Episodes

GET /api/ext/projects/{projectCode}/episodes

Path Parameters

Parameter Description
projectCode Human-readable project code, e.g. UNG_S1

Query Parameters

Parameter Required Description
shotNames No Pass 1 to include full per-episode shot list (default off)

Response 200 OK

{
  "project": {
    "id": "cmp6l5mzq0001ua0gz07bk72f",
    "name": "Ungo Season 1",
    "code": "UNG_S1",
    "showId": "UNG"
  },
  "episodes": [
    {
      "episode": "106",
      "shotCount": 42,
      "sequences": ["010", "020", "030"]
    }
  ]
}

When shotNames=1, each episode entry also includes a shots array with: id, shotCode, episode, sequence, status, exrOutput, seqTimecodeStart, seqTimecodeEnd, sourceClip, timecodeStart, timecodeEnd, clipDuration.


4. List Shots by Project Code

GET /api/ext/projects/{projectCode}/shots

Path Parameters

Parameter Description
projectCode Human-readable project code, e.g. UNG_S1

Query Parameters

Parameter Required Default Description
episode No Filter by episode, e.g. 106
sequence No Filter by sequence, e.g. 010
status No Filter by shot status
page No 1 Page number
limit No 200 Results per page (max 500)

Response 200 OK

{
  "project": { "id": "...", "name": "...", "code": "UNG_S1", "showId": "UNG" },
  "pagination": { "page": 1, "limit": 200, "total": 42, "pages": 1 },
  "shots": [
    {
      "id": "clxxxxxxxxxxxxxx",
      "shotCode": "UNG_106_010_020",
      "scene": "010",
      "episode": "106",
      "sequence": "010",
      "shotNumber": 20,
      "description": "Hero establishing wide",
      "status": "IN_PROGRESS",
      "priority": "NORMAL",
      "frameStart": 1001,
      "frameEnd": 1120,
      "fps": 24,
      "dueDate": "2026-08-01T00:00:00.000Z",
      "thumbnailUrl": null,
      "exrOutput": "UNG_106_010_020_cmp_TT_v003",
      "seqTimecodeStart": "00:59:49:12",
      "seqTimecodeEnd": "00:59:55:00",
      "sourceClip": "A106_C020_0601AB",
      "timecodeStart": "01:00:10:00",
      "timecodeEnd": "01:00:15:00",
      "clipDuration": "00:00:05:00",
      "artist": { "id": "...", "name": "Jane Smith", "email": "jane@studio.com" },
      "_count": { "versions": 3, "tasks": 2 }
    }
  ]
}

Note: shotVersion is not included in this response. Use the lookup endpoint to get it.


5. List Shots by Project ID

GET /api/ext/shots?projectId={projectId}

Legacy endpoint. Prefer /api/ext/projects/{projectCode}/shots for new integrations.

Query Parameters

Parameter Required Description
projectId Yes Database CUID of the project
episode No Filter by episode
status No Filter by shot status
shotCode No Return only the shot matching this exact code

Response 200 OK

{
  "shots": [ /* array of shot objects */ ],
  "total": 42
}

Shot objects include: id, shotCode, scene, episode, shotNumber, description, status, priority, frameStart, frameEnd, fps, dueDate, createdAt, updatedAt, artist, _count.

Note: Pipeline-specific fields (exrOutput, shotVersion, seqTimecodes, etc.) are not included. Use the lookup endpoint.


6. Get Single Shot

GET /api/ext/shots/{shotId}

By Database ID

GET /api/ext/shots/clxxxxxxxxxxxxxx

By Shot Code

GET /api/ext/shots/UNG_106_010_020?byCode=1&projectId=cmp6l5mzq0001ua0gz07bk72f
Query Param Description
byCode Set to 1 to treat the path segment as a shot code
projectId Required when byCode=1 to scope the lookup

Response 200 OK

Returns the same full shot object as the lookup endpoint, including tasks and latest version. Pipeline-specific fields (exrOutput, shotVersion, seqTimecodeStart, seqTimecodeEnd, sourceClip, etc.) are included.


7. Create Shot

POST /api/ext/shots
Content-Type: application/json

Accepts either application/json or multipart/form-data (when uploading a thumbnail file).

Request Body

Field Type Required Description
projectId string (CUID) Yes Database project ID
scene string Yes Scene identifier, alphanumeric + underscore, e.g. 010
episode string No Episode number. Required for EPISODIC projects
description string No Shot description
artistId string (CUID) No Assign to an artist by their DB id
priority string No LOW, NORMAL, HIGH, or URGENT (default NORMAL)
fps number No Frame rate (default 24)
frameStart integer No First frame number
frameEnd integer No Last frame number
dueDate string (ISO 8601) No Due date
thumbnailUrl string (URL) No Pre-hosted thumbnail URL
thumbnail File No Thumbnail image upload (multipart only, max 50 MB)
shotGroupName string No Shot group name — created automatically if it doesn't exist
shotCode string No Explicit shot code — bypasses auto-generation, must be unique in the project

Response 201 Created

{
  "shot": {
    "id": "clxxxxxxxxxxxxxx",
    "shotCode": "UNG_106_010_0010",
    "scene": "010",
    "episode": "106",
    "shotNumber": 10,
    "description": null,
    "status": "WAITING",
    "priority": "NORMAL",
    "fps": 24,
    "frameStart": null,
    "frameEnd": null,
    "dueDate": null,
    "thumbnailUrl": null,
    "projectId": "cmp6l5mzq0001ua0gz07bk72f",
    "artistId": null,
    "shotGroupId": null,
    "createdAt": "2026-07-21T09:00:00.000Z"
  }
}

Error 409 Conflict

Returned when an explicit shotCode already exists in the project:

{ "error": "A shot with that code already exists in this project", "shotCode": "UNG_106_010_020" }

8. Update Shot

PATCH /api/ext/shots/{shotId}
Content-Type: application/json

Used by pipeline tools to write back metadata after a render/upload.

Path Parameters

Parameter Description
shotId Database ID of the shot (from the lookup response shot.id)

Request Body

Field Type Required Validation Description
shotVersion string Yes* Must match v###, e.g. v004 Sets the current version string

*At least one field must be provided; currently only shotVersion is supported.

Example Request

PATCH /api/ext/shots/clxxxxxxxxxxxxxx
Authorization: Bearer your-api-key
Content-Type: application/json

{ "shotVersion": "v004" }

Response 200 OK

{ "success": true, "shot": { "id": "clxxxxxxxxxxxxxx", "shotVersion": "v004" } }

Error Responses

Status Meaning
400 Missing required parameter
401 Missing or invalid API key
403 Forbidden (session-auth routes only)
404 Resource not found
409 Conflict (duplicate shot code)
413 Payload too large (thumbnail > 50 MB)
422 Validation error
500 Internal server error
{ "error": "shotCode query param is required" }
{ "error": "Validation error", "details": [ ... ] }

After Effects Connector — Endpoints Used

For reference, the endpoints called by VFXReviewConnector.jsx:

Action Endpoint
Populate Episode dropdown GET /api/ext/projects/{PROJECT_CODE}/episodes
Populate Shot dropdown GET /api/ext/projects/{PROJECT_CODE}/shots?episode={value}
All shot operations (overlay, queue, preview, delivery) GET /api/ext/shots/lookup?shotCode={code}&projectCode={PROJECT_CODE}
Increment Shot Version PATCH /api/ext/shots/{shot.id} with { "shotVersion": "v00X" }