VFXReview External API Reference
Base URL: https://review.twotalesvfx.com
All requests require an Authorization header. Two formats are accepted:
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
1. List 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
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.)
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
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
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
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
Note: shotVersion is not included in this response. Use the lookup endpoint to get it.
5. List Shots by Project ID
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
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
By Database ID
By Shot Code
| 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
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
Error 409 Conflict
Returned when an explicit shotCode already exists in the project:
8. Update Shot
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
Response 200 OK
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 |
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" } |