246 lines
5.5 KiB
Markdown
246 lines
5.5 KiB
Markdown
# Shots API — External Integration Reference
|
|
|
|
Base URL: `https://review.twotalesvfx.com`
|
|
|
|
All requests must include an `Authorization` header with the configured API key.
|
|
|
|
---
|
|
|
|
## Authentication
|
|
|
|
```
|
|
Authorization: Bearer <API_SECRET_KEY>
|
|
```
|
|
|
|
The `API_SECRET_KEY` is set as an environment variable on the server. Contact your
|
|
system administrator for the key value.
|
|
|
|
---
|
|
|
|
## Endpoints
|
|
|
|
### 1. List Shots
|
|
|
|
```
|
|
GET /api/ext/shots?projectId={projectId}
|
|
```
|
|
|
|
Returns all shots for a project with optional filters.
|
|
|
|
#### Query Parameters
|
|
|
|
| Parameter | Required | Description |
|
|
|-------------|----------|----------------------------------------------------------|
|
|
| `projectId` | Yes | The project CUID (e.g. `cmp6l5mzq0001ua0gz07bk72f`) |
|
|
| `episode` | No | Filter by episode number (e.g. `103`) |
|
|
| `status` | No | Filter by shot status (see status values below) |
|
|
| `shotCode` | No | Return only the shot matching this exact code |
|
|
|
|
#### 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 |
|
|
|
|
#### Example Request
|
|
|
|
```http
|
|
GET /api/ext/shots?projectId=cmp6l5mzq0001ua0gz07bk72f&episode=103&status=COMPLETE
|
|
Authorization: Bearer your-api-key
|
|
```
|
|
|
|
#### Example Response
|
|
|
|
```json
|
|
{
|
|
"shots": [
|
|
{
|
|
"id": "clxxxxxxxxxxxxxx",
|
|
"shotCode": "UNG_103_010_010",
|
|
"scene": "010",
|
|
"episode": "103",
|
|
"shotNumber": 10,
|
|
"description": "Hero wide establishing shot",
|
|
"status": "COMPLETE",
|
|
"priority": "NORMAL",
|
|
"frameStart": 1001,
|
|
"frameEnd": 1120,
|
|
"fps": 24,
|
|
"dueDate": "2026-06-01T00:00:00.000Z",
|
|
"createdAt": "2026-05-20T10:00:00.000Z",
|
|
"updatedAt": "2026-05-28T14:30:00.000Z",
|
|
"artist": {
|
|
"id": "clxxxxxxxxxxxxxx",
|
|
"name": "Jane Smith",
|
|
"email": "jane@studio.com"
|
|
},
|
|
"_count": {
|
|
"versions": 3,
|
|
"tasks": 2
|
|
}
|
|
}
|
|
],
|
|
"total": 1
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 2. Get Single Shot
|
|
|
|
```
|
|
GET /api/ext/shots/{id}
|
|
```
|
|
|
|
Returns full detail for one shot including all tasks and the latest version status.
|
|
|
|
#### By Database ID
|
|
|
|
```http
|
|
GET /api/ext/shots/clxxxxxxxxxxxxxx
|
|
Authorization: Bearer your-api-key
|
|
```
|
|
|
|
#### By Shot Code
|
|
|
|
Add `byCode=1` and `projectId` to look up by the human-readable shot code instead:
|
|
|
|
```http
|
|
GET /api/ext/shots/UNG_103_010_010?byCode=1&projectId=cmp6l5mzq0001ua0gz07bk72f
|
|
Authorization: Bearer your-api-key
|
|
```
|
|
|
|
#### Example Response
|
|
|
|
```json
|
|
{
|
|
"shot": {
|
|
"id": "clxxxxxxxxxxxxxx",
|
|
"shotCode": "UNG_103_010_010",
|
|
"scene": "010",
|
|
"episode": "103",
|
|
"shotNumber": 10,
|
|
"description": "Hero wide establishing shot",
|
|
"status": "COMPLETE",
|
|
"priority": "NORMAL",
|
|
"frameStart": 1001,
|
|
"frameEnd": 1120,
|
|
"fps": 24,
|
|
"dueDate": "2026-06-01T00:00:00.000Z",
|
|
"createdAt": "2026-05-20T10:00:00.000Z",
|
|
"updatedAt": "2026-05-28T14:30:00.000Z",
|
|
"project": {
|
|
"id": "cmp6l5mzq0001ua0gz07bk72f",
|
|
"name": "UNG Episode 103",
|
|
"code": "UNG103",
|
|
"showId": "UNG"
|
|
},
|
|
"artist": {
|
|
"id": "clxxxxxxxxxxxxxx",
|
|
"name": "Jane Smith",
|
|
"email": "jane@studio.com"
|
|
},
|
|
"tasks": [
|
|
{
|
|
"id": "clxxxxxxxxxxxxxx",
|
|
"title": "Comp",
|
|
"type": "COMP",
|
|
"status": "DONE",
|
|
"priority": "NORMAL",
|
|
"estimatedHours": 8,
|
|
"dueDate": "2026-06-01T00:00:00.000Z",
|
|
"assignedArtist": {
|
|
"id": "clxxxxxxxxxxxxxx",
|
|
"name": "Jane Smith",
|
|
"email": "jane@studio.com"
|
|
},
|
|
"_count": {
|
|
"versions": 3
|
|
}
|
|
}
|
|
],
|
|
"versions": [
|
|
{
|
|
"id": "clxxxxxxxxxxxxxx",
|
|
"versionNumber": 3,
|
|
"approvalStatus": "APPROVED",
|
|
"createdAt": "2026-05-28T14:30:00.000Z",
|
|
"artist": {
|
|
"id": "clxxxxxxxxxxxxxx",
|
|
"name": "Jane Smith",
|
|
"email": "jane@studio.com"
|
|
}
|
|
}
|
|
],
|
|
"_count": {
|
|
"versions": 3,
|
|
"tasks": 2
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Error Responses
|
|
|
|
| Status | Meaning |
|
|
|--------|----------------------------------------------|
|
|
| `400` | Missing required parameter (e.g. projectId) |
|
|
| `401` | Missing or invalid API key |
|
|
| `404` | Shot not found |
|
|
| `500` | Internal server error |
|
|
|
|
```json
|
|
{ "error": "projectId is required" }
|
|
```
|
|
|
|
---
|
|
|
|
## Invoicing Use Cases
|
|
|
|
### Get all completed shots for billing
|
|
|
|
```http
|
|
GET /api/ext/shots?projectId={id}&status=COMPLETE
|
|
```
|
|
|
|
### Get all shots for a specific episode
|
|
|
|
```http
|
|
GET /api/ext/shots?projectId={id}&episode=103
|
|
```
|
|
|
|
### Get frame count for a shot (for per-frame billing)
|
|
|
|
From the single shot response, calculate:
|
|
|
|
```
|
|
frameCount = frameEnd - frameStart + 1
|
|
```
|
|
|
|
### Get estimated hours across all tasks for a shot
|
|
|
|
Sum `estimatedHours` from the `tasks` array in the single shot response.
|
|
|
|
---
|
|
|
|
## Shot Code Format
|
|
|
|
Shot codes follow the convention:
|
|
|
|
```
|
|
{showId}_{episode}_{scene}_{shotNumber}
|
|
|
|
e.g. UNG_103_010_010
|
|
^^^ ^^^ ^^^ ^^^
|
|
| | | shot number (padded)
|
|
| | scene
|
|
| episode
|
|
show ID
|
|
```
|