{"openapi":"3.1.0","info":{"title":"impartire API","version":"1.0.0","description":"The impartire public API. Authenticate with an org API key minted by an org admin on the Settings page:\n`Authorization: Bearer impk_…` (the header only — a key in the query string is ignored). A key's authority is its scopes, across the whole org; `<resource>:write` includes `<resource>:read`.\n\n## Scopes\n- `assets:read` — Read asset types, assets and their files\n- `assets:write` — Upload files, create, edit and delete assets (includes read)\n- `projects:read` — List projects and their playlists\n- `external-sources:write` — Register items from an external platform (Zype)\n- `projects:write` — Create and edit projects; create, edit and delete their playlists (includes read)\n- `tags:read` — List the org's tags\n- `workflows:read` — List the workflows a run can be started from\n- `runs:read` — Read workflow runs and their progress\n- `runs:write` — Start workflow runs (includes read)\n- `collections:read` — Read collections and their items\n- `collections:write` — Create, edit and delete collections and their items (includes read)\n- `records:read` — Read record types and records\n- `records:write` — Create, edit and delete records (includes read)\n- `review:read` — Read assets' review comments and clip markers\n- `people:read` — Read the org's people and their credits\n- `taxonomy:read` — Read the org's category taxonomy\n- `audit:read` — Read the org's audit log: who changed what, and when\n- `delivery:read` — Read delivery requirements, readiness, receipts, spec profiles and delivery targets\n- `epg:read` — Read the EPG: services, schedules, formats and the transmission log\n- `analytics:read` — Read consumption, operations and search analytics\n- `org:read` — Read the org's members, with their email addresses, roles and teams\n- `channels:read` — Read playout channels and their configuration (no stream keys)\n- `review:write` — Add, resolve and delete review comments and clip markers (includes read)\n- `runs:signal` — Cancel workflow runs (a key never approves, rejects, completes or skips a step)\n- `delivery:write` — Deliver content against a delivery requirement and reject received deliveries (includes read)\n- `schedules:write` — Create, change and remove programmes on the EPG schedule\n- `channels:control` — Start and stop playout channels\n- `access:write` — Grant and deny project access, bind teams to projects and move projects\n- `sharing:write` — Create and revoke public share links to assets\n\n## Errors\nEvery error is an RFC 9457 Problem (`application/problem+json`) whose `type` is `https://impartire.com/problems/<code>`. Branch on the code:\n- `unauthenticated` (401) — No credential was presented in the Authorization header, or the API key or OAuth token is unknown, revoked, expired, or for another resource. WWW-Authenticate names the resource_metadata to discover the authorization server from.\n- `insufficient-scope` (403) — The credential is valid but lacks a scope this operation requires; WWW-Authenticate names every missing scope.\n- `insufficient-permission` (403) — An OAuth token acts as its person, and they may see this resource but not make this change (or file into that project). Re-authorizing does not help; ask someone who may.\n- `not-found` (404) — The resource does not exist in this org, or the API is not enabled for it.\n- `validation` (422) — The request is well-formed but a field is invalid; `errors[]` names each field (`path`) and what is accepted.\n- `idempotency-mismatch` (422) — This Idempotency-Key was used with a different request (method, path or body) in the last 24 hours.\n- `idempotency-in-flight` (409) — A request with this Idempotency-Key is still being processed; retry after `Retry-After` seconds.\n- `precondition-failed` (412) — If-Match did not match the resource's current `edit_seq`; the body carries the current one.\n- `precondition-required` (428) — This write needs an If-Match header carrying the ETag (or the bare `edit_seq`) of the version being changed; GET the resource first.\n- `type-changed` (409) — The asset type's field schema changed since the `schema_version` the request was built against, and the fields no longer validate; GET the asset type and rebuild the fields.\n- `rate-limited` (429) — This key has used its request budget for the window; wait `Retry-After` seconds. `RateLimit-Policy` on every response states the budget.\n- `conflict` (409) — The request conflicts with the resource's current state.\n- `legal-hold` (409) — The asset is under legal hold, so it cannot be deleted, given a new file version (attach, replace, restore), delivered or scheduled to air, and a step of its runs cannot be signed off, rejected or skipped; `detail` gives the hold's reason. Only someone who may release the hold can lift it, in the app.\n- `unknown-workflow` (422) — `workflow_id` names no live workflow template this org can start; GET /api/v1/workflows lists them.\n- `unknown-asset` (422) — `asset_id` names no live asset of this org that the credential can read; GET /api/v1/assets lists them.\n- `unknown-tag` (422) — A tag `id` names no tag of this org that the credential can read; GET /api/v1/tags lists them, and `{ name }` coins a new org tag instead.\n- `invalid-hierarchy` (422) — The org's project hierarchy rules do not allow this: the project type is not allowed under its parent's type (or at the root, or above a sub-project's type), or the tree would be more than five levels deep. `detail` names the rule; the rules are set in the app.\n- `collection-constraint` (422) — The collection does not accept this asset: its type is not in `allowed_type_ids`, it carries none of `allowed_category_ids`, or the collection is published and the asset is not. `errors[].path` names the rule; GET the collection to see its constraints.\n- `already-member` (409) — The asset is already an item of this collection or playlist (an asset appears in one once); `item_id` in the body is the existing item.\n- `project-type-disallows` (422) — The project's type does not allow this (a playlist in a project whose type has playlists turned off). Pick another project, or change the type's settings in the app.\n- `confirmation-required` (403) — The workflow template reaches a delivery — its own action, a step's, or a sub-workflow's — which POST /runs never starts, with any credential. Deliver against a requirement with POST /api/v1/delivery-requirements/{id}/deliver (`delivery:write`, a guarded action); publish to a social platform in the app.\n- `confirmation-pending` (409) — The same action, on the same resource with the same parameters, is already waiting for its person to confirm it in impartire; `confirmation_id` and `confirm_url` name it. Poll GET /api/v1/confirmations/{id} instead of asking again.\n- `delivery-in-flight` (409) — The same file is already being delivered to the same destination for the same requirement; `receipt_id` and `run_id` name that delivery's receipt and run. Wait for the run to end before delivering again; a run parked as an incident stays active, so cancel it if it is stuck.\n- `confirmation-expired` (410) — Nobody confirmed the action within 15 minutes, so it will never run. Ask again for a new confirmation if it is still wanted.\n- `orchestration-unavailable` (502) — The run could not be handed to the orchestrator, so nothing was started; retry later (with the same Idempotency-Key).\n- `playout-unavailable` (502) — The playout engine could not be reached or did not start or stop the channel, so nothing changed on air; retry later (with the same Idempotency-Key).\n- `already-current` (422) — The file version named to restore is already its chain's current version, so there is nothing to restore; GET /api/v1/assets/{id}/files/{file_id} lists the chain's versions.\n- `upload-not-landed` (422) — The upload's bytes have not reached storage yet; PUT them to `upload_url` first (a multipart upload: PUT every part, then POST /api/v1/uploads/{id}/complete).\n- `not-multipart` (422) — The upload is a single PUT, so it has no parts to sign, complete or abort; PUT the whole file to its `upload_url`. POST /api/v1/uploads with `multipart: true` starts a multipart upload.\n- `size-mismatch` (422) — The completed multipart upload is not `size_bytes` long, so it was discarded and the upload failed; start a new upload with the file's exact size.\n- `storage-unavailable` (503) — The org's storage could not be reached; retry later.\n- `authorization-unavailable` (503) — The permission service could not be reached, so a change to who has access did not happen; retry later.\n- `authorization-write-failed` (500) — The write landed but its permission tuples could not be written, so it was rolled back (a create is soft-deleted, a move is reverted). On a create, retrying with the same Idempotency-Key replays this answer and a new key retries; a move can simply be retried.\n- `internal` (500) — Something failed on our side. The response carries no detail; quote `request_id` when reporting it.\n\n## Idempotency\nCreating POSTs accept an `Idempotency-Key` header (1–255 characters; a UUID is usual). The first request with a key reserves it; a retry with the same key and the same request (method + path + canonical JSON body) within 24 hours replays the stored response with `Idempotent-Replayed: true`; the same key with a different request is 422 `idempotency-mismatch`; a retry while the first is still running is 409 `idempotency-in-flight` with `Retry-After`. Responses that executed nothing (401, 403, 404, 422, 429) are not stored, so the key can be reused with a corrected request. GET requests are naturally idempotent and ignore the header.\n\n## Conventions\nLists take `limit` (default 50; larger values are treated as 100) and an opaque `cursor`, and return `{ data, next_cursor }` — `next_cursor: null` is the last page. Single resources send an `ETag` (it may arrive weak-prefixed through the CDN); send it back as received in `If-None-Match` for a 304. Every response carries `Request-Id`.\n\n## Rate limits\nEach key may make 600 requests per 60 seconds. Every response carries `RateLimit-Policy: \"default\";q=600;w=60` (draft-ietf-httpapi-ratelimit-headers). Over budget is 429 `rate-limited` with `Retry-After` and `RateLimit: \"default\";r=0;t=<seconds>`. GET /me reports the budget."},"servers":[{"url":"https://impartire.com/api/v1"}],"security":[{"apiKey":[]},{"oauth2":[]}],"paths":{"/openapi.json":{"get":{"operationId":"getOpenApiDocument","summary":"This document","security":[],"responses":{"200":{"description":"The OpenAPI 3.1 document.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/me":{"get":{"operationId":"getMe","summary":"Who is calling: the key, its org, its scopes and its request budget","description":"Any valid key may call it, whatever its scopes.","security":[{"apiKey":[]},{"oauth2":[]}],"responses":{"200":{"description":"The calling key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/asset-types":{"get":{"operationId":"listAssetTypes","summary":"List the asset types the org can create assets of, with their field definitions and file slots","description":"Each type's `fields` is the validation contract for `fields` on POST and PATCH /assets: a declared key must hold a value of its type.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"responses":{"200":{"description":"The asset types.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetTypeList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/projects":{"get":{"operationId":"listProjects","summary":"List the org's projects","description":"Ordered by name unless `sort` says otherwise. To poll for changes, pass `updated_after` with the newest `updated_at` you have seen and `sort=-updated_at` (or `updated_at`). A deleted project leaves the list.","security":[{"apiKey":["projects:read"]},{"oauth2":["projects:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}},{"name":"parent_id","in":"query","required":false,"description":"Only the direct children of this project.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"updated_after","in":"query","required":false,"description":"Only projects changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — poll with the newest `updated_at` you have seen (that project does not come back), sorted `-updated_at` or `updated_at`.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `name`. Ties break on id.","schema":{"type":"string","enum":["name","-name","updated_at","-updated_at"]}}],"responses":{"200":{"description":"A page of projects.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit`, `parent_id`, `updated_after`, `sort` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createProject","summary":"Create a project, optionally typed and under a parent","description":"A root project (no `parent_id`) is born Closed — org members see that it exists, admitted teams open it; a sub-project inherits its parent's access. The credential is the project's owner: for an API key, the key's service principal. Typed projects follow the org's hierarchy rules.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}}},"responses":{"201":{"description":"The created project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or type changes, `fp` with anything else the body shows. If-Match on PATCH compares `v`.","schema":{"type":"string"}},"Location":{"description":"The project's URL.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (name, description, parent_id, project_type_id), invalid-hierarchy, or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"authorization-write-failed — the project's permissions could not be written, so it was rolled back; or internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/projects/{id}":{"get":{"operationId":"getProject","summary":"Get one project","security":[{"apiKey":["projects:read"]},{"oauth2":["projects:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or type changes, `fp` with anything else the body shows. If-Match on PATCH compares `v`.","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateProject","summary":"Rename, describe or retype a project","description":"If-Match is required: send the ETag from the last GET (or from the create). A retype must fit the org's hierarchy rules under the parent's type and above each sub-project's type. Moving a project is POST /projects/{id}/move (guarded); changing its visibility is done in the app.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-Match","in":"header","required":true,"description":"The project's ETag.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequest"}}}},"responses":{"200":{"description":"The updated project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or type changes, `fp` with anything else the body shows. If-Match on PATCH compares `v`.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"precondition-failed — If-Match is stale; `etag` in the body is the current one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (empty body, name, description, project_type_id), or invalid-hierarchy.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"428":{"description":"precondition-required — no If-Match.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/projects/{id}/access":{"post":{"operationId":"grantProjectAccess","summary":"Give a member, team or role access to a project (guarded)","description":"A guarded action (ADR 0081): it changes who can see the project. The app's own write runs, with its checks and words. **An API key's write happens at once.** **An OAuth token's does not**: 202 with a Confirmation naming the project and who, by name; once its person confirms it in impartire it runs as them, every check again. Its person must manage the project (project manage; no platform-admin bypass). The subject must be a member, team or role of the org (422), a team not archived and a subject not denied on the project (409: lift the deny first). A team's or role's grant follows its membership. Audited: a `project.access_granted` event.","security":[{"apiKey":["access:write"]},{"oauth2":["access:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantProjectAccessRequest"}}}},"responses":{"201":{"description":"An API key's grant, written.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectGrant"}}}},"202":{"description":"An OAuth token's grant, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person can open the project but not manage it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — an archived team, or a subject denied on the project; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (a bad field; `subject_id` not of the org), or idempotency-mismatch (an OAuth token may not send Idempotency-Key).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"authorization-unavailable — the permission service could not be reached; nothing changed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"revokeProjectAccess","summary":"Take one access grant on a project away (guarded)","description":"A guarded action (ADR 0081): it changes who can see the project. The app's own write runs, with its checks and words. **An API key's write happens at once.** **An OAuth token's does not**: 202 with a Confirmation naming the project and who, by name; once its person confirms it in impartire it runs as them, every check again. Its person must manage the project. Names the grant by `subject_type`, `subject_id` and `level`; a subject that has since left the org can still be revoked. 404 when there is no such grant (nothing changed). Audited: a `project.access_revoked` event.","security":[{"apiKey":["access:write"]},{"oauth2":["access:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"subject_type","in":"query","required":true,"description":"member: one person (GET /api/v1/members). team: everyone in the team. role: everyone holding the role. A team's or role's grant follows its membership.","schema":{"type":"string","enum":["member","team","role"]}},{"name":"subject_id","in":"query","required":true,"description":"The subject the grant names.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"level","in":"query","required":true,"description":"viewer: read the project and everything filed under it. contributor: edit the project too. manager: administer it, including who has access. asset_contributor: edit the assets filed under it WITHOUT reading the project. asset_purger: delete them, likewise.","schema":{"type":"string","enum":["viewer","asset_contributor","asset_purger","contributor","manager"]}}],"responses":{"202":{"description":"An OAuth token's revoke, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"204":{"description":"An API key's revoke: the grant is gone."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person cannot manage the project.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"confirmation-pending.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a missing or bad `subject_type`, `subject_id` or `level`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"authorization-unavailable — the permission service could not be reached; nothing changed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/projects/{id}/deny":{"post":{"operationId":"denyProjectAccess","summary":"Deny a member, team or role on a project (guarded)","description":"A guarded action (ADR 0081): it changes who can see the project. The app's own write runs, with its checks and words. **An API key's write happens at once.** **An OAuth token's does not**: 202 with a Confirmation naming the project and who, by name; once its person confirms it in impartire it runs as them, every check again. Its person must manage the project. A deny removes read — and everything above it — on the project and everything under it, whatever else grants it, admins included (ADR 0047). A `reason` is required. Not yourself (422: you could not lift it); the subject must be the org's (422); already denied is 409. Audited: a `project.access_denied` event (its reason is not served by the audit log).","security":[{"apiKey":["access:write"]},{"oauth2":["access:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DenyProjectAccessRequest"}}}},"responses":{"201":{"description":"An API key's deny, written.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDeny"}}}},"202":{"description":"An OAuth token's deny, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person cannot manage the project.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — already denied; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (a bad field, yourself, a subject not of the org), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"authorization-unavailable — the permission service could not be reached; nothing changed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"liftProjectDeny","summary":"Lift a deny on a project (guarded)","description":"A guarded action (ADR 0081): it changes who can see the project. The app's own write runs, with its checks and words. **An API key's write happens at once.** **An OAuth token's does not**: 202 with a Confirmation naming the project and who, by name; once its person confirms it in impartire it runs as them, every check again. Its person must manage the project. The deny's record is kept, marked lifted. 404 when the subject has no active deny. Audited: a `project.deny_lifted` event.","security":[{"apiKey":["access:write"]},{"oauth2":["access:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"subject_type","in":"query","required":true,"description":"member: one person (GET /api/v1/members). team: everyone in the team. role: everyone holding the role. A team's or role's grant follows its membership.","schema":{"type":"string","enum":["member","team","role"]}},{"name":"subject_id","in":"query","required":true,"description":"The denied subject.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"202":{"description":"An OAuth token's lift, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"204":{"description":"An API key's lift: the deny no longer applies."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person cannot manage the project.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"confirmation-pending.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a missing or bad `subject_type` or `subject_id`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"authorization-unavailable — the deny is recorded as lifted but may still be enforced; deny again, then lift once the service is back.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/projects/{id}/teams":{"post":{"operationId":"bindProjectTeam","summary":"Assign a team to a production (guarded)","description":"A guarded action (ADR 0081): it changes who can see the project. The app's own write runs, with its checks and words. **An API key's write happens at once.** **An OAuth token's does not**: 202 with a Confirmation naming the project and who, by name; once its person confirms it in impartire it runs as them, every check again. Its person must administer the production (project administrate). The project must be a top-level project nobody owns and not itself a lane; the team the org's and not archived (422). The team's members read the production and get their own lane on it — a project the team owns, private to it. Idempotent: 201 when the lane was made, 200 when the team was already assigned. There is no unassign in the API (nor in the app). Audited: a `project.team_bound` event and the lane's capture.","security":[{"apiKey":["access:write"]},{"oauth2":["access:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BindProjectTeamRequest"}}}},"responses":{"200":{"description":"An API key's assignment: the team was already assigned; its lane.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductionLane"}}}},"201":{"description":"An API key's assignment: the lane was made.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductionLane"}}}},"202":{"description":"An OAuth token's assignment, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person does not administer the production.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"confirmation-pending, or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — `team_id` not a team of the org, an archived team, or a project that cannot be a production; idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"authorization-unavailable — the permission service could not be reached; retry (assigning again is safe).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/projects/{id}/move":{"post":{"operationId":"moveProject","summary":"Move a project under another, or to the top level (guarded)","description":"A guarded action (ADR 0081): a project reads through its permission root, so moving it changes who can see it. The app's own move runs: Unfiled, the Library, a lane (nesting) and a team space (nesting) stay put (409); the parent must be a project of the org (422), not inside the moved subtree, allowed by the org's hierarchy rules and no more than five levels deep (422 invalid-hierarchy); and a move may narrow or keep the project's audience, never widen it (422 — widen a root from its settings page in the app). A move that narrows it revokes the public share links to the assets under it. Its person must be able to update the project and the new parent (no platform-admin bypass). **An API key's move happens at once**: 200 with the Project. **An OAuth token's does not**: 202 with a Confirmation saying where it goes and what that does; once its person confirms it in impartire it runs as them, every check again. Moving a project to where it already is answers 200 at once, for either credential. Audited: a `project.moved` event and the row's capture.","security":[{"apiKey":["access:write"]},{"oauth2":["access:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveProjectRequest"}}}},"responses":{"200":{"description":"An API key's move (or no move needed): the project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or type changes, `fp` with anything else the body shows. If-Match on PATCH compares `v`.","schema":{"type":"string"}}}},"202":{"description":"An OAuth token's move, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person cannot update the project or the new parent.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — an infrastructure project; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (`parent_id` not a project of the org, its own subtree, or a move that would widen who can see it), invalid-hierarchy, or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"authorization-unavailable — the permission service could not be reached; nothing changed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/uploads":{"post":{"operationId":"createUpload","summary":"Presign a single PUT, or start a multipart upload, for a file (step 1 of creating an asset with a file)","description":"PUT the file's bytes to `upload_url` with `headers`, then create the asset with `file.upload_id` (or attach it to an existing asset with POST /assets/{id}/files). A single PUT carries up to 5 GiB. With `multipart: true` (required above 5 GiB, allowed from 5 MiB, up to 5 TiB) the answer has `method: MULTIPART`, no `upload_url` or `headers`, and `multipart`: the server-chosen `part_size_bytes` and `part_count`. Sign the parts' URLs with POST /uploads/{id}/parts, PUT each part, then POST /uploads/{id}/complete.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadRequest"}}}},"responses":{"201":{"description":"The upload: where and how to PUT the bytes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (e.g. size_bytes over 5 GiB without `multipart`, `multipart` under 5 MiB), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/uploads/{id}":{"get":{"operationId":"getUpload","summary":"Get an upload's status: pending, landed, consumed or expired","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"upload_id from POST /uploads.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The upload's status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadStatus"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/uploads/{id}/parts":{"post":{"operationId":"signUploadParts","summary":"Sign upload URLs for parts of a multipart upload","description":"Up to 100 distinct part numbers per request, each from 1 to `multipart.part_count`. PUT part n's bytes (offset (n-1)·`part_size_bytes`, `part_size_bytes` long, the last part the rest) to its URL within 15 minutes and keep the PUT's `ETag` header for …/complete. Signing writes nothing, so asking again just signs fresh URLs: no Idempotency-Key.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"upload_id from POST /uploads with `multipart: true`.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignPartsRequest"}}}},"responses":{"200":{"description":"One URL per requested part.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadPartUrlList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found — not this credential's upload, or no longer in progress (completed, aborted, used or expired).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (part_numbers), or not-multipart — the upload is a single PUT.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/uploads/{id}/complete":{"post":{"operationId":"completeUpload","summary":"Complete a multipart upload from its parts","description":"Every part once, in any order, each with the ETag its PUT answered. The assembled file must be `size_bytes` long: otherwise it is discarded, the upload fails, and the answer is 422 `size-mismatch`. On success the upload is `landed`, ready for POST /assets or POST /assets/{id}/files. Completing an upload already completed answers its status again.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"upload_id from POST /uploads with `multipart: true`.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteUploadRequest"}}}},"responses":{"200":{"description":"The upload's status: landed (or consumed, when completed and used before).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadStatus"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found — not this credential's upload, or aborted, failed or expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (parts — missing, repeated, or refused by storage), not-multipart, size-mismatch, or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/uploads/{id}/abort":{"post":{"operationId":"abortUpload","summary":"Abort a multipart upload in progress","description":"Frees the parts stored so far; the upload reads `expired`. Aborting again, or after completing, is 404.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"upload_id from POST /uploads with `multipart: true`.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Aborted."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found — not this credential's upload, or not in progress (completed, aborted, used).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"not-multipart — the upload is a single PUT.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets":{"get":{"operationId":"listAssets","summary":"List and search the org's assets","description":"Every current asset in the org, whatever project it is in. Filters combine with AND. Keyset-paginated; no total. To poll for changes, pass `updated_after` with the newest `updated_at` you have seen and `sort=-updated_at` (or `updated_at`).","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Case-insensitive substring of the asset's name. Characters are matched literally.","schema":{"type":"string"}},{"name":"type_id","in":"query","required":false,"description":"Only assets of this type (GET /api/v1/asset-types).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"project_id","in":"query","required":false,"description":"Only assets placed in this project (GET /api/v1/projects). Not its sub-projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"external_ref","in":"query","required":false,"description":"Only assets carrying exactly this external_ref.","schema":{"type":"string"}},{"name":"created_after","in":"query","required":false,"description":"Only assets created strictly after this instant (ISO 8601 with offset).","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"created_before","in":"query","required":false,"description":"Only assets created strictly before this instant (ISO 8601 with offset).","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"updated_after","in":"query","required":false,"description":"Only assets changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — poll with the newest `updated_at` you have seen (that asset does not come back), sorted `-updated_at` or `updated_at`.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"category_id","in":"query","required":false,"description":"Only assets assigned this org category directly (a category an asset inherits from its project does not count).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"media_type","in":"query","required":false,"description":"Only assets with a current file of this media type in one of their slots (derived files do not count). `other` is any slotted file that is not video, audio, image or document — subtitles, for one.","schema":{"type":"string","enum":["video","audio","image","document","other"]}},{"name":"tag","in":"query","required":false,"description":"Only assets carrying a tag of this name — exact, ignoring case and extra spaces. Repeat the parameter (up to 10 times) for assets carrying every one.","schema":{"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `-created_at` (newest first). Ties break on id.","schema":{"type":"string","enum":["created_at","-created_at","name","-name","updated_at","-updated_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of assets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetSummaryList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad filter (`type_id`, `project_id`, `category_id`, `media_type`, `tag`, a timestamp), `sort`, `limit` or `cursor` (a cursor replayed with different parameters).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createAsset","summary":"Create an asset in a project, optionally from a landed upload","description":"With `file`, the upload becomes the asset's first file and the slot's pipeline starts exactly as for a browser upload; `runs` shows what had started by the time of the response.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssetRequest"}}}},"responses":{"201":{"description":"The created asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}},"headers":{"ETag":{"description":"Strong validator: `\"<edit_seq>.<fp>\"`; `fp` changes when a file is attached, a run's status changes, or a tag is added or removed. If-Match accepts it or the bare `edit_seq`.","schema":{"type":"string"}},"Location":{"description":"The asset's URL.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (type_id, project_id, fields, file), upload-not-landed, or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}":{"get":{"operationId":"getAsset","summary":"Get an asset with its current files and recent runs","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}},"headers":{"ETag":{"description":"Strong validator: `\"<edit_seq>.<fp>\"`; `fp` changes when a file is attached, a run's status changes, or a tag is added or removed. If-Match accepts it or the bare `edit_seq`.","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateAsset","summary":"Update an asset's name, fields, project or external_ref","description":"If-Match is required: send the ETag from the last GET (or the bare `edit_seq`). `fields` replaces the whole bag. A `project_id` change moves the asset; filing it into a project that is not open revokes its share links.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-Match","in":"header","required":true,"description":"The asset's ETag, or its bare edit_seq.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAssetRequest"}}}},"responses":{"200":{"description":"The updated asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}},"headers":{"ETag":{"description":"Strong validator: `\"<edit_seq>.<fp>\"`; `fp` changes when a file is attached, a run's status changes, or a tag is added or removed. If-Match accepts it or the bare `edit_seq`.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"type-changed — the type's schema moved past `schema_version` and the fields no longer validate.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"precondition-failed — If-Match is stale; `edit_seq` in the body is the current one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (empty body, name, fields, project_id, external_ref).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"428":{"description":"precondition-required — no If-Match.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteAsset","summary":"Delete an asset (every version)","description":"Soft-deletes the asset; it no longer appears in reads or lists. No If-Match: deleting is idempotent by outcome, so a second DELETE is a 404. An asset under legal hold is refused with 409 `legal-hold`, whose detail gives the hold's reason.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Deleted."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"legal-hold — the asset is under legal hold.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/files":{"get":{"operationId":"listAssetFiles","summary":"List an asset's current files with their technical metadata","description":"Every current file of the asset — the ones attached to a slot, then the ones the pipeline derived (proxy, thumbnail, captions…) — in the order `Asset.files` uses, each with its version chain (`root_file_id`), who added it, its version note and `technical`: what the pipeline measured (duration, dimensions, codec, loudness), null until the measure pass has run. A derived file's `size_bytes` may be null. Returned whole: `next_cursor` is always null.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The asset's current files.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetFileList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"attachAssetFile","summary":"Attach an uploaded file to an asset, or replace one of its files with a new version","description":"`upload_id` is a landed upload this credential made (POST /uploads, then PUT the bytes). With `replace_file_id` (a current file of the asset) the upload becomes the next version of that file's chain; the old version is kept and stays downloadable. Without it, a slot that holds one file gets a new version of that file, and a slot that holds several (`multiple`) gets a new file beside the others. The slot is `replace_file_id`'s, else `slot_id`, else the type's one slot matching the file's media type. The slot's pipeline (proxy, captions, QC…) starts as for a browser upload; GET the asset for its `runs`. An OAuth token's person needs edit on the asset. An asset under legal hold is refused with 409 `legal-hold`.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachFileRequest"}}}},"responses":{"201":{"description":"The new file (or new version).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetFile"}}},"headers":{"Location":{"description":"The file's URL (GET it for its version chain).","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may see the asset but not edit it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"legal-hold — the asset is under legal hold; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (upload_id, slot_id, replace_file_id — not a current file of this asset, a derived file, or in another slot — version_note), upload-not-landed, or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/files/{file_id}":{"get":{"operationId":"getAssetFile","summary":"Get one file of an asset, any version, with its version chain","description":"By any version's id — current or not. `versions` lists the whole chain, newest first; download any of them with …/download. A file replaced (POST …/files with `replace_file_id`, or in the app) or restored (…/restore) is a new version in the same chain.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"file_id","in":"path","required":true,"description":"A file id from the asset's `files`, or any version's id from a file's `versions`.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The file and its chain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetFileVersions"}}},"headers":{"ETag":{"description":"Strong validator: `\"<the chain's current version>.<fp>\"`; `fp` changes when a version is added to the chain or the file is measured.","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/files/{file_id}/restore":{"post":{"operationId":"restoreAssetFile","summary":"Make an earlier version of a file current again","description":"`file_id` is an earlier version (an id from the file's `versions` whose `is_current` is false). Restoring appends: the chain gets a NEW version carrying that version's bytes, and every earlier row stays as it was. The body is optional; `version_note` defaults to \"Restored v<n>\". No pipeline runs (the bytes were processed when they first arrived). A derived file cannot be restored. An OAuth token's person needs edit on the asset. An asset under legal hold is refused with 409 `legal-hold`.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"file_id","in":"path","required":true,"description":"A file id from the asset's `files`, or any version's id from a file's `versions`.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreFileRequest"}}}},"responses":{"201":{"description":"The new current version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetFile"}}},"headers":{"Location":{"description":"The new version's URL.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may see the asset but not edit it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"legal-hold — the asset is under legal hold; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"already-current — that version is the chain's current one; validation (a derived file, version_note); or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/files/{file_id}/download":{"get":{"operationId":"getFileDownloadUrl","summary":"Get a short-lived URL for one of an asset's files, any version","description":"A presigned GET for a file of the asset — slotted or derived, the current version or any earlier one (an id from `versions`) — valid for 5 minutes. A download is an export: an OAuth token's person needs export on the asset (else 404). A JSON body, not a redirect; fetch `url` directly (no Authorization header). A file with no bytes in storage yet is a 404.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"file_id","in":"path","required":true,"description":"A file id from the asset's `files`, or any version's id from a file's `versions`.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"Where to fetch the bytes, until expires_at.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadUrl"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/workflows":{"get":{"operationId":"listWorkflows","summary":"List the workflow templates a run can be started from","description":"The org's live templates and the platform's system ones, ordered by name unless `sort` says otherwise (`updated_after` polls for changed ones). Each `param_schema` is what `params` on POST /runs is validated against. A template whose feature the org does not have is not listed; for an OAuth token, a team-private template only for a member of its team.","security":[{"apiKey":["workflows:read"]},{"oauth2":["workflows:read"]}],"parameters":[{"name":"updated_after","in":"query","required":false,"description":"Only templates changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — poll with the newest `updated_at` you have seen (that template does not come back).","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `name`. Ties break on id.","schema":{"type":"string","enum":["name","-name","updated_at","-updated_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of workflow templates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `updated_after`, `sort`, `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/workflows/{id}":{"get":{"operationId":"getWorkflow","summary":"Get one workflow template","security":[{"apiKey":["workflows:read"]},{"oauth2":["workflows:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The template's id, from GET /api/v1/workflows (any version's id resolves to the current version).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The template's current version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workflow"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/runs":{"get":{"operationId":"listRuns","summary":"List workflow runs, most recently changed first","description":"Every run of the org — started through the API, in the app, or by an upload. For an OAuth token, the runs on assets its person can read and the runs they started; a run of a team-private template they are not in is listed with `private: true` and no detail. Poll for progress with `updated_after`.","security":[{"apiKey":["runs:read"]},{"oauth2":["runs:read"]}],"parameters":[{"name":"asset_id","in":"query","required":false,"description":"Only runs on this asset (any version of it).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"workflow_id","in":"query","required":false,"description":"Only runs of this template (any version of it).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"status","in":"query","required":false,"description":"Only runs in this status.","schema":{"type":"string","enum":["active","completed","cancelled","failed"]}},{"name":"updated_after","in":"query","required":false,"description":"Only runs whose state changed strictly after this instant, compared to the millisecond — poll with the newest `updated_at` you have seen (that run does not come back).","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad filter (`asset_id`, `workflow_id`, `status`, `updated_after`), `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"startRun","summary":"Start a workflow run on an asset","description":"Runs the app's start checks — the template and the asset exist in the org, `params` match the template's `param_schema` — then hands the run to the orchestrator. 202: the run has started, not finished; poll GET /runs/{id} until `status` leaves `active`, or until `current_step.awaiting` is `approval` or `completion` (a person's turn, in the app). A template that can deliver — its own action, a step's, or a sub_workflow child's, recursively — is refused for every credential (403 `confirmation-required`, naming the step): deliver against a requirement with POST /delivery-requirements/{id}/deliver; a social publish is done in the app. For an OAuth token its person needs create_workflow in the org and read on the asset.","security":[{"apiKey":["runs:write"]},{"oauth2":["runs:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartRunRequest"}}}},"responses":{"202":{"description":"The started run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Run"}}},"headers":{"Location":{"description":"The run's URL.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, insufficient-permission, or confirmation-required — a template that reaches a delivery, with any credential (deliver with POST /delivery-requirements/{id}/deliver; publish a social delivery in the app).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found — the template's action needs a feature the org does not have.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"unknown-workflow, unknown-asset, validation (`params` against the template's `param_schema`), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"502":{"description":"orchestration-unavailable — nothing was started; retry.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/runs/{id}":{"get":{"operationId":"getRun","summary":"Get one workflow run: its status, current step and steps","security":[{"apiKey":["runs:read"]},{"oauth2":["runs:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The run's id, from POST /api/v1/runs or GET /api/v1/runs.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Run"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/runs/{id}/signals":{"post":{"operationId":"signalRun","summary":"Approve, reject, complete or skip a run's step, or cancel the run (guarded)","description":"A guarded action (ADR 0081). The app's own checks run: the step must be one of the run's and still open, the run active; for a person, the step's completion authority (who may sign for it), a skip's director-or-above rule, and standing on any `output_asset_id`. On an asset under legal hold, approve, reject, complete and skip are 409 `legal-hold` (cancel is always allowed). **An API key may only `cancel`**: it runs at once and answers 200 with the run (poll it until `status` is `cancelled`); any other kind is 403 `insufficient-permission` — attesting to work must name a person. **An OAuth token's signal does not run**: it answers 202 with a Confirmation and its Location; show the person `confirm_url`, then poll GET /confirmations/{id} — once they confirm, the signal runs as them and the confirmation's `result` is the run. The same ask while one waits is 409 `confirmation-pending`. Audited: a `run.signalled` event on the run.","security":[{"apiKey":["runs:signal"]},{"oauth2":["runs:signal"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The run's id, from POST /api/v1/runs or GET /api/v1/runs.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalRunRequest"}}}},"responses":{"200":{"description":"An API key's cancel, handed to the orchestrator: the run as it is now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Run"}}}},"202":{"description":"An OAuth token's signal, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an API key's attesting signal, or (on confirm) a person who may not sign for the step.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — the run is not active, the step is already closed, or the run has not reached the orchestrator; legal-hold — the asset is held (not for cancel); confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (`workflow_step_id` missing or not a step of this run, an automated step to skip, a deliverable the step requires, `output_asset_id` with another kind), or idempotency-mismatch (an OAuth token may not send Idempotency-Key).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"502":{"description":"orchestration-unavailable — the signal did not reach the orchestrator; nothing happened.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tags":{"get":{"operationId":"listTags","summary":"List the org's tags","description":"Org tags and team tags, ordered by name, each with how many assets and projects carry it. For an OAuth token, a team tag is listed only when its person is in the team (or an org admin).","security":[{"apiKey":["tags:read"]},{"oauth2":["tags:read"]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Only tags whose name starts with this, ignoring case and extra spaces.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of tags.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/collections":{"get":{"operationId":"listCollections","summary":"List the org's collections","description":"Ordered by name unless `sort` says otherwise. To poll for changes, pass `updated_after` with the newest `updated_at` you have seen and `sort=-updated_at` (or `updated_at`); `updated_at` moves when the name, description or constraints change, not when items do. A deleted collection leaves the list. For an OAuth token, the collections filed in a project its person can open.","security":[{"apiKey":["collections:read"]},{"oauth2":["collections:read"]}],"parameters":[{"name":"project_id","in":"query","required":false,"description":"Only collections filed in this project (GET /api/v1/projects). Not its sub-projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"parent_id","in":"query","required":false,"description":"Only the collections nested directly in this one.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"root_only","in":"query","required":false,"description":"`true`: only collections not nested in another. Default false.","schema":{"type":"string","enum":["true","false"]}},{"name":"q","in":"query","required":false,"description":"Case-insensitive substring of the collection's name. Characters are matched literally.","schema":{"type":"string"}},{"name":"updated_after","in":"query","required":false,"description":"Only collections changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — poll with the newest `updated_at` you have seen (that collection does not come back), sorted `-updated_at` or `updated_at`.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `name`. Ties break on id.","schema":{"type":"string","enum":["name","-name","updated_at","-updated_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of collections.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit`, `project_id`, `parent_id`, `root_only`, `updated_after`, `sort` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createCollection","summary":"Create a collection, filed in a project and optionally nested in another","description":"Born a draft. `project_id` is its permission parent (omitted: the org's Unfiled project); `parent_id` nests it for browsing only. The credential is the collection's owner: for an API key, the key's service principal. An OAuth token's person needs create_collection in the org, contribute on a named project, and update on a named parent collection.","security":[{"apiKey":["collections:write"]},{"oauth2":["collections:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionRequest"}}}},"responses":{"201":{"description":"The created collection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Collection"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or constraints change, `fp` with anything else the body shows and whenever an item is added, removed or reordered. If-Match on PATCH compares `v`.","schema":{"type":"string"}},"Location":{"description":"The collection's URL.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may not create collections, add to that project, or nest in that collection.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (name, description, project_id, parent_id, allowed_type_ids, allowed_category_ids), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"authorization-write-failed — the collection's permissions could not be written, so it was rolled back; or internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/collections/{id}":{"get":{"operationId":"getCollection","summary":"Get one collection","security":[{"apiKey":["collections:read"]},{"oauth2":["collections:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The collection's id, from GET /api/v1/collections.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The collection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Collection"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or constraints change, `fp` with anything else the body shows and whenever an item is added, removed or reordered. If-Match on PATCH compares `v`.","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateCollection","summary":"Rename or describe a collection, or change its constraints","description":"If-Match is required: send the ETag from the last GET (or from the create). Changing a constraint does not remove items already in the collection. `status` is not settable — publishing and archiving are lifecycle acts done in the app — and an unknown field is a 422. An OAuth token's person needs update on the collection.","security":[{"apiKey":["collections:write"]},{"oauth2":["collections:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The collection's id, from GET /api/v1/collections.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-Match","in":"header","required":true,"description":"The collection's ETag.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCollectionRequest"}}}},"responses":{"200":{"description":"The updated collection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Collection"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or constraints change, `fp` with anything else the body shows and whenever an item is added, removed or reordered. If-Match on PATCH compares `v`.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the collection but not change it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"precondition-failed — If-Match is stale; `etag` in the body is the current one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (empty body, an unknown field such as `status`, name, description, allowed_type_ids, allowed_category_ids).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"428":{"description":"precondition-required — no If-Match.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteCollection","summary":"Delete a collection","description":"Soft-deletes the collection; it no longer appears in reads or lists. Its assets are untouched. No If-Match: a second DELETE is a 404. An OAuth token's person needs delete on the collection.","security":[{"apiKey":["collections:write"]},{"oauth2":["collections:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The collection's id, from GET /api/v1/collections.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Deleted."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the collection but not delete it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/collections/{id}/children":{"get":{"operationId":"listChildCollections","summary":"List the collections nested in a collection","description":"The collections nested directly in this one, by name. For an OAuth token, only those its person can open.","security":[{"apiKey":["collections:read"]},{"oauth2":["collections:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The collection's id, from GET /api/v1/collections.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of child collections.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/collections/{id}/items":{"get":{"operationId":"listCollectionItems","summary":"List a collection's items in order","description":"Ordered by `sort_order`, then by when each was added. Paginated: the list is bounded by the collection, a page at a time. Each item names its asset's current version. For an OAuth token, an item whose asset its person may not read keeps its place and id but is `restricted` with `asset: null`.","security":[{"apiKey":["collections:read"]},{"oauth2":["collections:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The collection's id, from GET /api/v1/collections.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of items.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"addCollectionItem","summary":"Add an asset to a collection","description":"Pins the asset's current version. Without `sort_order` the item goes after the last one. The collection's constraints apply: a type not in `allowed_type_ids`, an asset with none of `allowed_category_ids`, or an unpublished asset in a published collection is 422 `collection-constraint`, `errors[].path` naming the rule. An asset already in the collection (any version of it) is 409 `already-member`. An OAuth token's person needs update on the collection and read on the asset.","security":[{"apiKey":["collections:write"]},{"oauth2":["collections:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The collection's id, from GET /api/v1/collections.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCollectionItemRequest"}}}},"responses":{"201":{"description":"The new item.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItem"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the collection but not change it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"already-member — the asset is already in the collection (`item_id` in the body); or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"collection-constraint, unknown-asset, validation (asset_id, sort_order), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/collections/{id}/items/{item_id}":{"delete":{"operationId":"removeCollectionItem","summary":"Remove an item from a collection","description":"The asset itself is untouched. A second DELETE is a 404. An OAuth token's person needs update on the collection.","security":[{"apiKey":["collections:write"]},{"oauth2":["collections:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The collection's id, from GET /api/v1/collections.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"item_id","in":"path","required":true,"description":"The item's id, from GET /api/v1/collections/{id}/items.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Removed."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the collection but not change it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/collections/{id}/items/order":{"put":{"operationId":"reorderCollectionItems","summary":"Put a collection's items in a new order","description":"`item_ids` is every item of the collection, each exactly once, in the new order; their `sort_order` becomes 0, 1, 2… Anything else (a missing, repeated or foreign id) is a 422. A collection of more than 1000 items is reordered in the app. Answers the whole list after. If an item was added or removed meanwhile, nothing moves and the answer is 409 `conflict`: read the items and send the order again. Safe to repeat: no Idempotency-Key, no If-Match. An OAuth token's person needs update on the collection.","security":[{"apiKey":["collections:write"]},{"oauth2":["collections:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The collection's id, from GET /api/v1/collections.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderCollectionItemsRequest"}}}},"responses":{"200":{"description":"Every item, in the new order (`next_cursor` null).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionItemList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the collection but not change it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — the collection's items changed while it was being reordered; nothing moved.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — `item_ids` is not every item exactly once, or the collection is too large to reorder here.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/playlists":{"get":{"operationId":"listPlaylists","summary":"List a project's playlists","description":"`project_id` is required: playlists are listed one project at a time. Ordered by name unless `sort` says otherwise. To poll for changes, pass `updated_after` with the newest `updated_at` you have seen and `sort=-updated_at` (or `updated_at`); `updated_at` moves when the name, description or target_count change, not when items do. A deleted playlist leaves the list. An OAuth token's person needs read on the project (a project they cannot open is a 422 like a missing one).","security":[{"apiKey":["projects:read"]},{"oauth2":["projects:read"]}],"parameters":[{"name":"project_id","in":"query","required":true,"description":"Required: the project whose playlists to list (GET /api/v1/projects). Not its sub-projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"updated_after","in":"query","required":false,"description":"Only playlists changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — pass the newest `updated_at` you have seen and that playlist is not returned again.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `name`. Ties break on id.","schema":{"type":"string","enum":["name","-name","updated_at","-updated_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of playlists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaylistList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a missing or unknown `project_id`, or a bad `limit`, `updated_after`, `sort` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createPlaylist","summary":"Create a playlist in a project","description":"A typed project's type must allow playlists (an untyped project always does); otherwise 422 `project-type-disallows`. An OAuth token's person needs update on the project.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePlaylistRequest"}}}},"responses":{"201":{"description":"The created playlist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Playlist"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or target_count change, `fp` with anything else the body shows and whenever an item is added, removed, reordered or given a new position. If-Match on PATCH compares `v`.","schema":{"type":"string"}},"Location":{"description":"The playlist's URL.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the project but not update it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"project-type-disallows, validation (project_id, name, description, target_count), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/playlists/{id}":{"get":{"operationId":"getPlaylist","summary":"Get one playlist","security":[{"apiKey":["projects:read"]},{"oauth2":["projects:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The playlist's id, from GET /api/v1/playlists?project_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The playlist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Playlist"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or target_count change, `fp` with anything else the body shows and whenever an item is added, removed, reordered or given a new position. If-Match on PATCH compares `v`.","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updatePlaylist","summary":"Rename or describe a playlist, or change its target count","description":"If-Match is required: send the ETag from the last GET (or from the create). An unknown field is a 422; moving a playlist to another project is not in v1. An OAuth token's person needs update on the playlist's project.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The playlist's id, from GET /api/v1/playlists?project_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-Match","in":"header","required":true,"description":"The playlist's ETag.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePlaylistRequest"}}}},"responses":{"200":{"description":"The updated playlist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Playlist"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` moves when the name, description or target_count change, `fp` with anything else the body shows and whenever an item is added, removed, reordered or given a new position. If-Match on PATCH compares `v`.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the project but not update it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"precondition-failed — If-Match is stale; `etag` in the body is the current one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (empty body, an unknown field, name, description, target_count).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"428":{"description":"precondition-required — no If-Match.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deletePlaylist","summary":"Delete a playlist","description":"Soft-deletes the playlist; it no longer appears in reads or lists. Its assets are untouched. No If-Match: a second DELETE is a 404. An OAuth token's person needs update on the playlist's project.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The playlist's id, from GET /api/v1/playlists?project_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Deleted."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the project but not update it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/playlists/{id}/items":{"get":{"operationId":"listPlaylistItems","summary":"List a playlist's items in order","description":"Ordered by `sort_order`, then by when each was added. Paginated: the list is bounded by the playlist, a page at a time. Each item names its asset's current version. For an OAuth token, an item whose asset its person may not read keeps its place and id but is `restricted` with `asset: null`.","security":[{"apiKey":["projects:read"]},{"oauth2":["projects:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The playlist's id, from GET /api/v1/playlists?project_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of items.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaylistItemList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"addPlaylistItem","summary":"Append an asset to a playlist","description":"Pins the asset's current version and appends it after the last item; `position` is an optional editorial slot number, independent of the order. An asset already in the playlist (any version of it) is 409 `already-member`. An OAuth token's person needs update on the playlist's project and read on the asset.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The playlist's id, from GET /api/v1/playlists?project_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddPlaylistItemRequest"}}}},"responses":{"201":{"description":"The new item.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaylistItem"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the project but not update it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"already-member — the asset is already in the playlist (`item_id` in the body); or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"unknown-asset, validation (asset_id, position), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/playlists/{id}/items/{item_id}":{"delete":{"operationId":"removePlaylistItem","summary":"Remove an item from a playlist","description":"The asset itself is untouched; the other items keep their `sort_order`. A second DELETE is a 404. An OAuth token's person needs update on the playlist's project.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The playlist's id, from GET /api/v1/playlists?project_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"item_id","in":"path","required":true,"description":"The item's id, from GET /api/v1/playlists/{id}/items.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Removed."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the project but not update it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/playlists/{id}/items/order":{"put":{"operationId":"reorderPlaylistItems","summary":"Put a playlist's items in a new order","description":"`item_ids` is every item of the playlist, each exactly once, in the new order; their `sort_order` becomes 0, 1, 2… (`position` is untouched). Anything else (a missing, repeated or foreign id) is a 422. A playlist of more than 1000 items is reordered in the app. Answers the whole list after. If an item was added or removed meanwhile, nothing moves and the answer is 409 `conflict`: read the items and send the order again. Safe to repeat: no Idempotency-Key, no If-Match. An OAuth token's person needs update on the playlist's project.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The playlist's id, from GET /api/v1/playlists?project_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderPlaylistItemsRequest"}}}},"responses":{"200":{"description":"Every item, in the new order (`next_cursor` null).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaylistItemList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may open the project but not update it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — the playlist's items changed while it was being reordered; nothing moved.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — `item_ids` is not every item exactly once, or the playlist is too large to reorder here.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/record-types":{"get":{"operationId":"listRecordTypes","summary":"List the org's record types and their fields","description":"Every live record type of the org (custom objects: a Product, a Contract…), by name, each with its live field definitions in the app's form order — the contract `fields` on POST / PATCH /records is validated against. A `reference` field names its target in `reference_target`. Deprecated definitions, and for an OAuth token the ones its person may not read, are left out. The list is returned whole. All 404 when the org does not have custom records.","security":[{"apiKey":["records:read"]},{"oauth2":["records:read"]}],"responses":{"200":{"description":"The record types.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordTypeList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/records":{"get":{"operationId":"listRecords","summary":"List one record type's records","description":"`type_id` is required: records are listed one type at a time. Newest first unless `sort` says otherwise. To poll for changes, pass `updated_after` with the newest `updated_at` you have seen and `sort=-updated_at` (or `updated_at`); a deleted record leaves the list. Each record carries its `fields` and its `references` resolved to names. For an OAuth token, records its person may not read are left out (a page may be short and still have a next one) and the fields they may not read are stripped. All 404 when the org does not have custom records.","security":[{"apiKey":["records:read"]},{"oauth2":["records:read"]}],"parameters":[{"name":"type_id","in":"query","required":true,"description":"Required: the record type whose records to list (GET /api/v1/record-types).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"q","in":"query","required":false,"description":"Case-insensitive substring of the record's title. Characters are matched literally.","schema":{"type":"string"}},{"name":"project_id","in":"query","required":false,"description":"Only records filed under this project (GET /api/v1/projects).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"updated_after","in":"query","required":false,"description":"Only records changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — pass the newest `updated_at` you have seen and that record is not returned again.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `-created_at` (newest first, as the app lists them). Ties break on id.","schema":{"type":"string","enum":["created_at","-created_at","title","-title","updated_at","-updated_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a missing or unknown `type_id` (an asset type's id included), an unknown `project_id`, or a bad `limit`, `updated_after`, `sort` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createRecord","summary":"Create a record","description":"`fields` is validated against the record type (GET /record-types): a reference field holds the target's id (an array when `multiple`) — a live asset, a record of the declared type, or a project of the org. Its reference edges are written with the record. `project_id` files it under a project; it does not change who may read it (records are org-wide). An OAuth token's person needs create_asset in the org (the app's permission for records), and may not send a field they cannot read. All 404 when the org does not have custom records.","security":[{"apiKey":["records:write"]},{"oauth2":["records:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRecordRequest"}}}},"responses":{"201":{"description":"The created record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Record"}}},"headers":{"ETag":{"description":"Strong validator: `\"<edit_seq>.<fp>\"`; `edit_seq` moves when the title or fields change, `fp` with anything else the body shows (a referenced asset, record or project renamed, for one). If-Match on PATCH accepts it or the bare `edit_seq`.","schema":{"type":"string"}},"Location":{"description":"The record's URL.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may not create records, or sent a field they cannot read.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (type_id, title, project_id, or `fields.<key>` naming each invalid value), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"authorization-write-failed — the record's permissions could not be written, so it was rolled back; or internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/records/{id}":{"get":{"operationId":"getRecord","summary":"Get one record","security":[{"apiKey":["records:read"]},{"oauth2":["records:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The record's id, from GET /api/v1/records?type_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Record"}}},"headers":{"ETag":{"description":"Strong validator: `\"<edit_seq>.<fp>\"`; `edit_seq` moves when the title or fields change, `fp` with anything else the body shows (a referenced asset, record or project renamed, for one). If-Match on PATCH accepts it or the bare `edit_seq`.","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateRecord","summary":"Retitle a record or replace its fields","description":"If-Match is required: the ETag from the last GET (or the create), or the bare `edit_seq`. `fields` replaces the whole bag (send back what GET returned, changed) and the reference edges follow it. An unknown field (`type_id`, `project_id`) is a 422. An OAuth token's person needs edit on the record; a field they cannot read is kept as it was and may not be sent. All 404 when the org does not have custom records.","security":[{"apiKey":["records:write"]},{"oauth2":["records:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The record's id, from GET /api/v1/records?type_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-Match","in":"header","required":true,"description":"The record's ETag, or its bare edit_seq.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecordRequest"}}}},"responses":{"200":{"description":"The updated record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Record"}}},"headers":{"ETag":{"description":"Strong validator: `\"<edit_seq>.<fp>\"`; `edit_seq` moves when the title or fields change, `fp` with anything else the body shows (a referenced asset, record or project renamed, for one). If-Match on PATCH accepts it or the bare `edit_seq`.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may read the record but not edit it, or sent a field they cannot read.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"precondition-failed — If-Match is stale; `edit_seq` in the body is the current one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (empty body, an unknown field, title, or `fields.<key>` naming each invalid value).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"428":{"description":"precondition-required — no If-Match.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteRecord","summary":"Delete a record","description":"Soft-deletes the record; it no longer appears in reads, lists or referenced-by. No If-Match: a second DELETE is a 404. An OAuth token's person needs delete on the record. All 404 when the org does not have custom records.","security":[{"apiKey":["records:write"]},{"oauth2":["records:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The record's id, from GET /api/v1/records?type_id=.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Deleted."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may read the record but not delete it.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/referenced-by":{"get":{"operationId":"listAssetReferencedBy","summary":"List the records that reference an asset","description":"Every live record whose reference field points at the asset (any of its versions), as `{ record, field_key, field_name }` — a record pointing at it through two fields appears twice — ordered by the record's title. For an OAuth token, records its person may not read and fields they may not read are left out, so a page may be short and still have a next one. 404 when the org does not have custom records, and for an asset the credential cannot read.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of referencing records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferencingRecordList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/comments":{"get":{"operationId":"listAssetComments","summary":"List an asset's review comments","description":"Every comment on the asset (any of its versions — comments belong to the asset), flat: thread them by `parent_id`. In conversation order (`created_at`) unless `sort` says otherwise. `resolved=true|false` keeps only resolved or open comments (a reply on its own state). To poll, pass `updated_after` with the newest `updated_at` you have seen (compared to the millisecond, so that comment does not come back) and `sort=updated_at`; editing, resolving or reopening a comment moves its `updated_at`, and a deleted comment simply leaves the list. Written with POST (and PATCH / DELETE one) under `review:write`. 404 for an asset the credential cannot read (for an OAuth token, read on the asset).","security":[{"apiKey":["review:read"]},{"oauth2":["review:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"resolved","in":"query","required":false,"description":"`true`: only resolved comments; `false`: only open ones. Omitted: both. A reply is filtered on its own state, not its thread's.","schema":{"type":"string","enum":["true","false"]}},{"name":"updated_after","in":"query","required":false,"description":"Only comments changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — pass the newest `updated_at` you have seen and that comment is not returned again.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `created_at` (conversation order, as the app shows them). Ties break on id.","schema":{"type":"string","enum":["created_at","-created_at","updated_at","-updated_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of comments.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `resolved`, `updated_after`, `sort`, `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createAssetComment","summary":"Comment on an asset, or reply to a comment","description":"Adds a review comment as the credential: an OAuth token writes as its person, who needs read on the asset (anyone who can see an asset may comment, as in the app); an API key writes as the org's API service principal, shown as `API`. `timestamp_seconds` pins it to a point in the media; `parent_id` makes it a reply to a comment on the same asset. Audited (the `comment` entries of GET /audit-log). Not a guarded action.","security":[{"apiKey":["review:write"]},{"oauth2":["review:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommentRequest"}}}},"responses":{"201":{"description":"The new comment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Comment"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (`body` blank or too long, `timestamp_seconds`, `parent_id` not a comment on this asset), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/comments/{comment_id}":{"patch":{"operationId":"updateAssetComment","summary":"Resolve or reopen a comment, or change its text","description":"`resolved: true` marks it resolved, `false` reopens it; `body` replaces its text. For an OAuth token, its person may resolve, reopen (and delete) their own comments and any on an asset they may edit, and change the text of their own only; an API key may resolve or reopen any comment of its org and change the text only of comments written with the org's keys. Moves `updated_at`.","security":[{"apiKey":["review:write"]},{"oauth2":["review:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"comment_id","in":"path","required":true,"description":"The comment's id, from GET /api/v1/assets/{id}/comments.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommentRequest"}}}},"responses":{"200":{"description":"The comment after.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Comment"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — not the author (for the text), or neither the author nor an editor of the asset.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — neither `resolved` nor `body`, or a blank `body`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteAssetComment","summary":"Delete a comment","description":"Hard-deletes it, as the app does. A comment with replies cannot be deleted (409 `conflict`): delete the replies first, or resolve it. A second DELETE is a 404. For an OAuth token, its person's own comments and any on an asset they may edit; an API key, any comment of its org.","security":[{"apiKey":["review:write"]},{"oauth2":["review:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"comment_id","in":"path","required":true,"description":"The comment's id, from GET /api/v1/assets/{id}/comments.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Deleted."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — neither the author nor an editor of the asset.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — the comment has replies.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/markers":{"get":{"operationId":"listAssetMarkers","summary":"List an asset's clip markers","description":"The asset's clip markers (labelled time ranges; any of its versions), in timeline order unless `sort` says otherwise. Returned whole: the app allows at most 3 per asset. `updated_after` (compared to the millisecond) keeps only markers made after it — markers are not edited, only made and deleted (POST and DELETE under `review:write`). 404 for an asset the credential cannot read (for an OAuth token, read on the asset).","security":[{"apiKey":["review:read"]},{"oauth2":["review:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"updated_after","in":"query","required":false,"description":"Only markers changed strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Default `start_seconds` (timeline order, as the app shows them); or `updated_at` / `-updated_at`. Ties break on id.","schema":{"type":"string","enum":["start_seconds","updated_at","-updated_at"]}}],"responses":{"200":{"description":"The asset's markers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkerList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `updated_after` or `sort`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createAssetMarker","summary":"Mark a time range on an asset","description":"Adds a clip marker as the credential (an OAuth token's person needs read on the asset; an API key marks as the org's API service principal, `API`). At most 3 per asset, as in the app: one more is 409 `conflict` — delete one first. Audited (the `marker` entries of GET /audit-log).","security":[{"apiKey":["review:write"]},{"oauth2":["review:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMarkerRequest"}}}},"responses":{"201":{"description":"The new marker.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Marker"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — the asset already has 3 markers; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (`end_seconds` not after `start_seconds`, a negative time, a label over 200 characters), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/markers/{marker_id}":{"delete":{"operationId":"deleteAssetMarker","summary":"Delete a clip marker","description":"Hard-deletes it, as the app does. A second DELETE is a 404. For an OAuth token, its person's own markers and any on an asset they may edit; an API key, any marker of its org.","security":[{"apiKey":["review:write"]},{"oauth2":["review:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"marker_id","in":"path","required":true,"description":"The marker's id, from GET /api/v1/assets/{id}/markers.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Deleted."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — neither its creator nor an editor of the asset.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/share-links":{"get":{"operationId":"listShareLinks","summary":"List an asset's public share links","description":"Newest first: whether each has a password, its expiry, clip and download setting, how often it was opened, who made it. Never a link's URL or token — those are returned once, when the link is made — and never its password. For an OAuth token, its person must be able to share the asset (asset share), as in the app (403 otherwise; 404 when they cannot open it).","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of links.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinkList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person cannot share the asset.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createShareLink","summary":"Make a public share link to an asset (guarded)","description":"A guarded action (ADR 0081): anyone holding the link can watch the asset without signing in. The app's own write runs: a password is stored salted and hashed (the viewer enters it on the link's page; it is never sent in a URL); a clip pins the link to a cut; an asset under legal hold is 409 `legal-hold`. **An API key's link is made at once**: 201 with the link and its `url` — the ONLY time the URL is returned; keep it as you would a password. **An OAuth token's is not**: 202 with a Confirmation naming the asset, the expiry, download and password; once its person confirms it in impartire the link is made as them, and the confirmation's `result` is the CreatedShareLink with its `url` (readable only by the app and person that asked). Its person must be able to share the asset (no platform-admin bypass). Audited: a `share_link.created` event and the row's capture.","security":[{"apiKey":["sharing:write"]},{"oauth2":["sharing:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShareLinkRequest"}}}},"responses":{"201":{"description":"An API key's link, made — with its URL, once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedShareLink"}}}},"202":{"description":"An OAuth token's link, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person cannot share the asset.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"legal-hold — the asset is held; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (a bad field; a clip with one end, or an end not after its start), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/share-links/{link_id}":{"delete":{"operationId":"revokeShareLink","summary":"Revoke a public share link (guarded)","description":"A guarded action (ADR 0081): the link stops working for everyone who has it, at once. For an OAuth token, the link's creator or a person who can share the asset, as in the app. **An API key's revoke happens at once** (204). **An OAuth token's does not**: 202 with a Confirmation; once its person confirms it in impartire the link is revoked as them. Audited: a `share_link.revoked` event and the row's capture.","security":[{"apiKey":["sharing:write"]},{"oauth2":["sharing:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"link_id","in":"path","required":true,"description":"The link's id, from GET /api/v1/assets/{id}/share-links or its create.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"202":{"description":"An OAuth token's revoke, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"204":{"description":"An API key's revoke: the link is gone."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — neither its creator nor someone who can share the asset.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"confirmation-pending.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/lineage":{"get":{"operationId":"getAssetLineage","summary":"Get an asset's derivation lineage","description":"What the asset derives from (`ancestors`) and what derives from it (`descendants`) — proxies, clips promoted from it, deliveries — over the lineage graph, one node per asset at its smallest depth, at most 64 steps each way, returned whole. Where an edge joins another organisation (a delivery to or from it) the walk stops and the node is a **boundary**: `asset: null`, `restricted: true`, `boundary: { org_name, role, receipt_id }` — nothing of the other org's asset or graph. For an OAuth token, an asset in the graph its person may not read keeps its place, depth and type with `asset: null` and `restricted: true`. 404 for an asset the credential cannot read.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The lineage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lineage"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/playback":{"get":{"operationId":"getAssetPlayback","summary":"Get an asset's playback descriptor","description":"What a player needs to play the asset's primary video: `status` (`ready`, `processing` or `none`), the HLS manifest URL (`hls_url`, carrying its signed access token when the delivery is signed), the poster, the WebVTT caption tracks and the progressive MP4 proxies. Every URL is short-lived: `expires_at` is the earliest moment one may stop working, so fetch the descriptor again rather than caching a URL. `processing` carries no URL; `none` means there is no HLS ladder to play (no video, a failed or missing transcode, or a delivery the API cannot play yet) — proxies, captions and poster are still listed where they exist. The original upload is never served here: playing is a read, the original is an export (`GET /assets/{id}/files/{file_id}/download`). 404 for an asset the credential cannot read (for an OAuth token, read on the asset).","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The playback descriptor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Playback"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"storage-unavailable — the URLs or the delivery's access token could not be signed; retry.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/credits":{"get":{"operationId":"listAssetCredits","summary":"List the people credited on an asset","description":"The asset's credits (credits belong to the asset, not a version): `{ id, person, role, billing_order }`, by billing order (unset last), then name. Returned whole, at most 500. Archived people are left out. Read only: credits are given in the app. 404 for an asset the credential cannot read (for an OAuth token, read on the asset). 404 when the org does not have people.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The asset's credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetCreditList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/categories":{"get":{"operationId":"listAssetCategories","summary":"List an asset's categories","description":"The categories assigned to the asset's current version, each with its group, returned whole — the assignments `GET /assets?category_id=` matches on (a category the asset's project carries is not listed). Read only: categories are assigned in the app. 404 for an asset the credential cannot read (for an OAuth token, read on the asset). 404 when the org does not have categories.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The asset's categories.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetCategoryList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/people":{"get":{"operationId":"listPeople","summary":"List the org's people","description":"The org's people (talent, crew, contributors) — archived ones left out — by name unless `sort` says otherwise. `q` searches name and bio; `nationality` matches exactly. To poll, pass `updated_after` with the newest `updated_at` you have seen (compared to the millisecond, so that person does not come back) and `sort=updated_at`; an archived person leaves the list. For an OAuth token, empty unless its person may read the org's people. Read only. 404 when the org does not have people.","security":[{"apiKey":["people:read"]},{"oauth2":["people:read"]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Case-insensitive substring of the name or the bio (as the app's people search).","schema":{"type":"string"}},{"name":"nationality","in":"query","required":false,"description":"Exact nationality, as the app stores it.","schema":{"type":"string"}},{"name":"updated_after","in":"query","required":false,"description":"Only people changed strictly after this instant (ISO 8601 with offset), compared to the millisecond — pass the newest `updated_at` you have seen and that person is not returned again.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Default `name` (case-insensitive, the app's order); `-name`, `updated_at`, `-updated_at`. Ties break on id.","schema":{"type":"string","enum":["name","-name","updated_at","-updated_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of people.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `updated_after`, `sort`, `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/people/{id}":{"get":{"operationId":"getPerson","summary":"Get a person","description":"One person of the org. Archived, foreign or (for an OAuth token whose person may not read the org's people) unreadable → 404. Send the ETag back in If-None-Match for a 304. 404 when the org does not have people.","security":[{"apiKey":["people:read"]},{"oauth2":["people:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The person's id, from GET /api/v1/people.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Person"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds (moves when the person is edited in the app), `fp` moves with anything else the body shows (`credit_count`).","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/people/{id}/credits":{"get":{"operationId":"listPersonCredits","summary":"List a person's credits","description":"The credits the person holds, from the asset's side — each asset (its current version) with its type, role and billing order — by asset name, paginated. A credit on a deleted asset is not listed. For an OAuth token, only assets its person may read. 404 for a person the credential cannot read. 404 when the org does not have people.","security":[{"apiKey":["people:read"]},{"oauth2":["people:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The person's id, from GET /api/v1/people.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonCreditList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/categories":{"get":{"operationId":"listCategories","summary":"List the org's asset categories","description":"The org's category taxonomy for assets — categories whose group is for assets or for every kind of thing — each with its group, by group (as the app orders them) then name. Returned whole, at most 1000. Use an id with `GET /assets?category_id=`. Read only: the taxonomy is managed in the app. For an OAuth token, empty unless its person is a member of the org. 404 when the org does not have categories.","security":[{"apiKey":["taxonomy:read"]},{"oauth2":["taxonomy:read"]}],"responses":{"200":{"description":"The categories.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/audit-log":{"get":{"operationId":"listAuditLog","summary":"List the org's audit trail","description":"Who changed what and when, newest first, as a projected feed: each entry names the resource (a public type, its id and name), the actor, the request it belongs to, a semantic event's public ids where there is one, and the public fields that changed — never the stored row images, and only the KEYS of an asset's or a record's `fields`. Something the feed does not describe is `resource.type: other` with no name and no changes. Filters combine with AND; `since` / `until` are exclusive. An `event` entry's changes are on the entry with the same `request_id`. For an OAuth token, its person needs the view-audit-log permission (no platform-admin bypass). 404 when the org does not have the audit log, and for an OAuth token whose person may not view it.","security":[{"apiKey":["audit:read"]},{"oauth2":["audit:read"]}],"parameters":[{"name":"resource_type","in":"query","required":false,"description":"Only entries about this kind of resource.","schema":{"type":"string","enum":["asset","file","project","collection","playlist","record","tag","tag_link","asset_type","field_definition","workflow","spec_profile","api_key","run","receipt","delivery_requirement","delivery_target","schedule_slot","service","channel","share_link","comment","marker","confirmation","other"]}},{"name":"resource_id","in":"query","required":false,"description":"Only entries about this resource (its id as `resource.id` shows it — for an asset, a version's id).","schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"actor_kind","in":"query","required":false,"description":"Only entries made by this kind of actor.","schema":{"type":"string","enum":["user","api_key","oauth","system","orchestration","unknown"]}},{"name":"action","in":"query","required":false,"description":"Only entries with this action.","schema":{"type":"string","enum":["created","updated","deleted","event"]}},{"name":"request_id","in":"query","required":false,"description":"Only the entries one request produced.","schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"since","in":"query","required":false,"description":"Only entries strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"until","in":"query","required":false,"description":"Only entries strictly before this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of entries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEntryList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad filter, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/audit-log/{id}":{"get":{"operationId":"getAuditEntry","summary":"Get one audit entry","description":"One entry, in the list's shape. 404 when the org does not have the audit log, and for an OAuth token whose person may not view it.","security":[{"apiKey":["audit:read"]},{"oauth2":["audit:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The entry's id, from GET /api/v1/audit-log.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The entry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEntry"}}},"headers":{"ETag":{"description":"Strong validator: a digest of the entry as served (the entry never changes; a name it shows may).","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-requirements":{"get":{"operationId":"listDeliveryRequirements","summary":"List the org's delivery requirements","description":"Standing demands: content in a project's subtree must meet a pinned spec profile, for a client, delivered to a target. Poll with `updated_after` (exclusive, millisecond). For an OAuth token, its person needs the read-delivery permission (no platform-admin bypass); a key reads the whole org. 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"project_id","in":"query","required":false,"description":"Only the requirements bound to this project (not its ancestors' or descendants').","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"status","in":"query","required":false,"description":"Only requirements with this status.","schema":{"type":"string","enum":["active","fulfilled","cancelled"]}},{"name":"updated_after","in":"query","required":false,"description":"Only requirements changed strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `-updated_at`. Ties break on id.","schema":{"type":"string","enum":["-updated_at","updated_at","created_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of requirements.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryRequirementList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad filter, `sort`, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-requirements/{id}":{"get":{"operationId":"getDeliveryRequirement","summary":"Get one delivery requirement","description":"One requirement, in the list's shape. 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The requirement's id, from GET /api/v1/delivery-requirements.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The requirement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryRequirement"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-requirements/{id}/readiness":{"get":{"operationId":"getDeliveryReadiness","summary":"Read a requirement's readiness","description":"Every asset in the requirement's project subtree (current versions, by asset id) against its pinned spec — the app's readiness matrix for this requirement, a page of assets at a time. A passing verdict on any of an asset's files counts (a conformed rendition). Reading it is a demand: for an ACTIVE requirement, an asset's current deliverable file that has no verdict for the spec yet is evaluated now (and stored), as the app does; a fulfilled or cancelled requirement is served from stored verdicts only. 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The requirement's id, from GET /api/v1/delivery-requirements.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"limit","in":"query","required":false,"description":"Assets per page, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"The requirement and a page of its assets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryReadiness"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-requirements/{id}/receipts":{"get":{"operationId":"listRequirementReceipts","summary":"List a requirement's receipts","description":"GET /delivery-receipts pre-filtered to the requirement (404 for an unknown one). 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The requirement's id, from GET /api/v1/delivery-requirements.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"asset_id","in":"query","required":false,"description":"Only deliveries of this asset: any version's id or its root id matches every version's receipts.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"status","in":"query","required":false,"description":"Only receipts with this status.","schema":{"type":"string","enum":["pending","delivered","failed","rejected"]}},{"name":"created_after","in":"query","required":false,"description":"Only receipts created strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of receipts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryReceiptList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad filter, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-requirements/{id}/deliver":{"post":{"operationId":"deliverRequirement","summary":"Deliver an asset against a requirement (guarded)","description":"A guarded action (ADR 0081): it moves content out of the org. The app's own deliver runs: the asset must be one of the org's, a file of it must pass the requirement's spec (`file_id` pins one; otherwise the best, a conformed rendition first), the destination (`target_id`, or the requirement's own) must be able to take it — for another org on the platform, an active supply link and a spec revision it still accepts. Then a Deliver run pushes the file and a receipt is opened in the org's ledger. The same file already in flight to the same destination for the requirement is 409 `delivery-in-flight` (`receipt_id` names it); an asset under legal hold is 409 `legal-hold`. **An API key's delivery starts at once**: 202 with the run and the receipt (poll either). **An OAuth token's does not**: 202 with a Confirmation naming the asset, the destination and the spec revision; once its person confirms it in impartire the delivery starts as them, and the confirmation's `result` is the Delivery. Its person needs the deliver permission in the org (asked first: 403 for any requirement id without it) and read on the asset. Audited: the receipt's capture and a `delivery.requested` event.","security":[{"apiKey":["delivery:write"]},{"oauth2":["delivery:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The requirement's id, from GET /api/v1/delivery-requirements.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliverRequest"}}}},"responses":{"202":{"description":"An API key's delivery, started: its run and its receipt. (An OAuth token's 202 body is a `Confirmation` waiting for its person instead — see the description.)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Delivery"}}},"headers":{"Location":{"description":"The receipt's URL (a key), or the confirmation's (a token): poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person may not deliver in the org.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found — the org does not have delivery, or the requirement is not one of the org's.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"delivery-in-flight (`receipt_id` and `run_id` name it); legal-hold; conflict — the requirement is not active, no file passes its spec, the destination is not ready or will not accept it; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"unknown-asset, validation (a bad field, or `target_id` not a target of the org), or idempotency-mismatch (an OAuth token may not send Idempotency-Key).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"502":{"description":"orchestration-unavailable — the delivery run did not start; nothing was delivered.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-receipts":{"get":{"operationId":"listDeliveryReceipts","summary":"List the org's delivery receipts","description":"The org's delivery ledger, newest first: one receipt per delivery attempt (a redelivery is a new receipt), to a target or to a social platform. A delivery to another org on the platform carries `attestation` (the supplier's verdict and, once landed, the file's SHA-256). Receipts have no `updated_at`; poll new ones with `created_after` and re-read a pending one by id. For an OAuth token, its person needs the read-delivery permission (no platform-admin bypass); a key reads the whole org. 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"asset_id","in":"query","required":false,"description":"Only deliveries of this asset: any version's id or its root id matches every version's receipts.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"requirement_id","in":"query","required":false,"description":"Only deliveries made for this requirement.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"status","in":"query","required":false,"description":"Only receipts with this status.","schema":{"type":"string","enum":["pending","delivered","failed","rejected"]}},{"name":"created_after","in":"query","required":false,"description":"Only receipts created strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of receipts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryReceiptList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad filter, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-receipts/{id}":{"get":{"operationId":"getDeliveryReceipt","summary":"Get one delivery receipt","description":"One receipt, in the list's shape. 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The receipt's id, from GET /api/v1/delivery-receipts.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryReceipt"}}},"headers":{"ETag":{"description":"Strong validator: a digest of the body as served.","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-receipts/{id}/reject":{"post":{"operationId":"rejectDelivery","summary":"Reject a delivery made to the org (guarded)","description":"A guarded action (ADR 0081). The receiving org refuses a delivery another org made to it through a supply link (`{id}` from GET /inbound-deliveries): a `delivered` one becomes `rejected` with `rejection_note`, which the supplier reads on their receipt; the landed asset stays in your intake project. **An API key's rejection happens at once** (200). **An OAuth token's does not**: 202 with a Confirmation naming the asset and the supplier; its person, an org admin, confirms it in impartire. Audited: a `receipt.rejected` event in your org. 404 when the org does not have delivery, and for an OAuth token whose person may not read it. Also 404 when the org does not have supply links.","security":[{"apiKey":["delivery:write"]},{"oauth2":["delivery:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The delivery's id, from GET /api/v1/inbound-deliveries (the supplier's receipt id).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectDeliveryRequest"}}}},"responses":{"200":{"description":"An API key's rejection: the delivery as it is now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundDelivery"}}}},"202":{"description":"An OAuth token's rejection, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person is not an org admin.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — the delivery is not `delivered`; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (`rejection_note` missing or empty), or idempotency-mismatch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/inbound-deliveries":{"get":{"operationId":"listInboundDeliveries","summary":"List deliveries made to the org","description":"The receiver's view: what other orgs delivered to yours through a supply link, newest first, with where each landed in your org. For an OAuth token, its person needs the read-delivery permission (no platform-admin bypass); a key reads the whole org. 404 when the org does not have delivery, and for an OAuth token whose person may not read it. Also 404 when the org does not have supply links.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"status","in":"query","required":false,"description":"Only deliveries with this status.","schema":{"type":"string","enum":["pending","delivered","failed","rejected"]}},{"name":"created_after","in":"query","required":false,"description":"Only deliveries created strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of inbound deliveries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundDeliveryList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad filter, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/spec-profiles":{"get":{"operationId":"listSpecProfiles","summary":"List the spec profiles the org may read","description":"Every technical delivery spec revision your org may read: its own, those another org published to it, and those its requirements pin. Who a spec is published to is not shown. For an OAuth token, its person needs the read-delivery permission (no platform-admin bypass); a key reads the whole org. 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"updated_after","in":"query","required":false,"description":"Only specs changed strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"sort","in":"query","required":false,"description":"Sort key; a leading `-` is descending. Default `name`. Ties break on id.","schema":{"type":"string","enum":["name","-updated_at","updated_at"]}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of spec profiles.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpecProfileList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad filter, `sort`, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/spec-profiles/{id}":{"get":{"operationId":"getSpecProfile","summary":"Get one spec profile","description":"One spec revision, in the list's shape; 404 for one your org may not read. 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The spec profile revision's id, from GET /api/v1/spec-profiles.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The spec profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpecProfile"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/delivery-targets":{"get":{"operationId":"listDeliveryTargets","summary":"List the org's delivery targets","description":"Where the org delivers to: an S3-compatible bucket outside the platform, or another org through a supply link (left out when the org does not have supply links). Never a target's transport configuration or credentials. For an OAuth token, its person needs the read-delivery permission (no platform-admin bypass); a key reads the whole org. 404 when the org does not have delivery, and for an OAuth token whose person may not read it.","security":[{"apiKey":["delivery:read"]},{"oauth2":["delivery:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of targets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryTargetList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/services":{"get":{"operationId":"listServices","summary":"List the org's broadcast services","description":"The org's linear broadcast services (EPG channels) — each with its transmission spec, its fallback format and the formats bound to it — by sort_order, as the app lists them. Returned whole, at most 1000. Poll with `updated_after` (exclusive, millisecond). For an OAuth token, its person needs membership of the org (no platform-admin bypass); a key reads the whole org. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["epg:read"]},{"oauth2":["epg:read"]}],"parameters":[{"name":"updated_after","in":"query","required":false,"description":"Only services changed strictly after this instant (ISO 8601 with offset), compared to the millisecond. A format binding added or removed does not change a service's `updated_at`; its ETag moves.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}}],"responses":{"200":{"description":"The services.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `updated_after`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/services/{id}":{"get":{"operationId":"getService","summary":"Get one broadcast service","description":"One service, in the list's shape. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["epg:read"]},{"oauth2":["epg:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The service's id, from GET /api/v1/services.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The service.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Service"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/schedules":{"get":{"operationId":"listSchedules","summary":"List a service's schedule in a window","description":"The programme slots of one service that overlap [from, to) — at most 31 days — by start time. Each slot carries its readiness as last evaluated (reading does not re-evaluate it). Poll a window with `updated_after` (exclusive, millisecond); a deleted slot simply stops appearing. For an OAuth token, its person needs membership of the org (no platform-admin bypass); a key reads the whole org. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org. Also 404 for a service that is not the org's.","security":[{"apiKey":["epg:read"]},{"oauth2":["epg:read"]}],"parameters":[{"name":"service_id","in":"query","required":true,"description":"The service whose schedule to read (GET /api/v1/services lists them). Required.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"from","in":"query","required":true,"description":"The start of the window (ISO 8601 with offset). Required.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"to","in":"query","required":true,"description":"The end of the window (ISO 8601 with offset), after `from` and at most 31 days after it. Required. Slots overlapping [from, to) are listed.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"updated_after","in":"query","required":false,"description":"Only slots changed strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of slots.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleSlotList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a missing or bad `service_id`, `from` or `to`, a window wider than allowed, a bad filter, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createScheduleSlot","summary":"Put a programme on a service's schedule (guarded)","description":"A guarded action (ADR 0081): it changes what airs. The app's own schedule write runs: every id the slot names must be the org's — the service, the format, the asset (by its current version's id or its root id), the source project or collection, and the pinned file must be a file of the asset (any version) — else 422 naming the field; the file that airs is pinned (`file_id`, or the asset's primary video); the slot's readiness is evaluated against the service's spec; the transmission log is re-derived and the on-air graphic re-pushed. An asset under legal hold is 409 `legal-hold`. **An API key's slot is made at once**: 201 with the slot and its ETag. **An OAuth token's is not**: 202 with a Confirmation naming the programme, the service, its airtime and what airs; once its person confirms it in impartire the slot is made as them (every check again), and the confirmation's `result` is the ScheduleSlot. Its person must be an org admin (the app's verb; no platform-admin bypass). Audited: the slot's capture and a `schedule.created` event. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["schedules:write"]},{"oauth2":["schedules:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateScheduleSlotRequest"}}}},"responses":{"201":{"description":"An API key's slot, made.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleSlot"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}},"Location":{"description":"The slot's URL.","schema":{"type":"string"}}}},"202":{"description":"An OAuth token's slot, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person is not an org admin.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"legal-hold — the asset is held; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (a bad field; `service_id`, `format_id`, `file_id`, `source_project_id` or `source_collection_id` not the org's; `ends_at` not after `starts_at`; both sources; `file_id` without `asset_id`), unknown-asset (`asset_id`), or idempotency-mismatch (an OAuth token may not send Idempotency-Key).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/schedules/{id}":{"get":{"operationId":"getScheduleSlot","summary":"Get one schedule slot","description":"One slot, in the list's shape. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["epg:read"]},{"oauth2":["epg:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The slot's id, from GET /api/v1/schedules.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The slot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleSlot"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"operationId":"updateScheduleSlot","summary":"Move or change a schedule slot (guarded)","description":"A guarded action (ADR 0081): it changes what airs. If-Match is required: the slot's ETag from the last GET (or the create), or its bare `v`. Send only the fields to change. The app's own write runs, with the same org checks as the create (422 naming the field); a new asset re-pins the file that airs and re-evaluates readiness, as does a move to another service; the transmission log is re-derived for the old and the new airtime and the on-air graphic re-pushed. Naming an asset under legal hold, or changing only the pinned file of a slot whose asset is held, is 409 `legal-hold`. **An API key's change happens at once** (200 with the slot and its new ETag). **An OAuth token's does not**: 202 with a Confirmation saying what moves or changes, by name; on confirm it applies only if the slot is still the version the person was shown (else the confirmation's `problem` is a 412). Its person must be an org admin. Audited: the slot's capture and a `schedule.updated` event. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["schedules:write"]},{"oauth2":["schedules:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The slot's id, from GET /api/v1/schedules.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-Match","in":"header","required":true,"description":"The slot's ETag, or its bare version.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateScheduleSlotRequest"}}}},"responses":{"200":{"description":"An API key's change: the slot as it is now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleSlot"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"202":{"description":"An OAuth token's change, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person is not an org admin.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"legal-hold — the named asset is held, or only the file changes on a slot whose asset is held; or confirmation-pending.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"precondition-failed — If-Match is stale; `etag` in the body is the current one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (no field, a bad field, an id not the org's, `ends_at` not after `starts_at`, both sources, `file_id` on a slot with no asset), or unknown-asset (`asset_id`).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"428":{"description":"precondition-required — no If-Match.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteScheduleSlot","summary":"Remove a schedule slot (guarded)","description":"A guarded action (ADR 0081): it changes what airs. The slot leaves the schedule and its transmission log; the on-air graphic is re-pushed. No If-Match, and never refused for a legal hold — taking a programme off air is not held. **An API key's removal happens at once** (204). **An OAuth token's does not**: 202 with a Confirmation naming the programme, the service and its airtime; the confirmation's `result` is null. Its person must be an org admin. Audited: the slot's capture and a `schedule.deleted` event. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["schedules:write"]},{"oauth2":["schedules:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The slot's id, from GET /api/v1/schedules.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"202":{"description":"An OAuth token's removal, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"204":{"description":"An API key's removal: the slot is gone."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person is not an org admin.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"confirmation-pending.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/transmission-log":{"get":{"operationId":"listTransmissionLog","summary":"Read a service's planned transmission log","description":"The events of one service's transmission log that overlap [from, to) — at most 7 days — by start time: each slot's programme, and the breaks and IDs its format places inside it. This is the PLANNED log, derived from the schedule and re-derived whenever the schedule changes; it is not an as-run record (none exists yet). Events have no `updated_at`: re-read the window. For an OAuth token, its person needs membership of the org (no platform-admin bypass); a key reads the whole org. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org. Also 404 for a service that is not the org's.","security":[{"apiKey":["epg:read"]},{"oauth2":["epg:read"]}],"parameters":[{"name":"service_id","in":"query","required":true,"description":"The service whose log to read (GET /api/v1/services lists them). Required.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"from","in":"query","required":true,"description":"The start of the window (ISO 8601 with offset). Required.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"to","in":"query","required":true,"description":"The end of the window (ISO 8601 with offset), after `from` and at most 7 days after it. Required. Events overlapping [from, to) are listed.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of log events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransmissionLog"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a missing or bad `service_id`, `from` or `to`, a window wider than allowed, a bad `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/formats":{"get":{"operationId":"listFormats","summary":"List the org's broadcast formats","description":"The org's clocks — the structure of a programme slot as segments, breaks and IDs with their durations — by name. Poll with `updated_after` (exclusive, millisecond). For an OAuth token, its person needs membership of the org (no platform-admin bypass); a key reads the whole org. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["epg:read"]},{"oauth2":["epg:read"]}],"parameters":[{"name":"updated_after","in":"query","required":false,"description":"Only formats changed strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of formats.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormatList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `updated_after`, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/formats/{id}":{"get":{"operationId":"getFormat","summary":"Get one broadcast format","description":"One format, in the list's shape. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["epg:read"]},{"oauth2":["epg:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The format's id, from GET /api/v1/formats.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The format.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Format"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/analytics/summary":{"get":{"operationId":"getAnalyticsSummary","summary":"Read consumption analytics over a range","description":"The numbers of the app's analytics dashboard: views, unique viewers, playback time and downloads over `range` reporting days ending today (the org's reporting day — its time zone and start hour — not a UTC calendar day), the same over the range before it, one point per day, the ten most viewed assets, and the device and audience breakdowns. `viewer_type` filters to one audience (`api` — developer-API downloads). Reading it first materializes every reporting day that has ended into the rollup, as the app's dashboard does (a write of derived data only). Channel audience is not served. For an OAuth token, its person needs membership of the org (no platform-admin bypass) and an asset's name is null when they may not read the asset; a key reads the whole org. 404 when the org does not have analytics, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["analytics:read"]},{"oauth2":["analytics:read"]}],"parameters":[{"name":"range","in":"query","required":false,"description":"How many reporting days, today included. Default `30d`.","schema":{"type":"string","enum":["7d","30d","90d","365d"]}},{"name":"viewer_type","in":"query","required":false,"description":"Filter to one audience. Default `all`.","schema":{"type":"string","enum":["all","internal","consumer","embed","api"]}}],"responses":{"200":{"description":"The consumption figures.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumptionAnalytics"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `range` or `viewer_type` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/analytics/operations":{"get":{"operationId":"getAnalyticsOperations","summary":"Read operations analytics over a range","description":"The numbers of the app's operations view over `range` reporting days ending today: workflow runs started, completed, failed and open, with durations; approvals and their latency; open incidents; delivery attempts, outcomes and latency; assets created, time to first approval, and the assets nobody opened. `workflows.active` and `incidents.active` are true now, not range figures. For an OAuth token, its person needs membership of the org (no platform-admin bypass) and an asset's name is null when they may not read the asset; a key reads the whole org. 404 when the org does not have analytics, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["analytics:read"]},{"oauth2":["analytics:read"]}],"parameters":[{"name":"range","in":"query","required":false,"description":"How many reporting days, today included. Default `30d`.","schema":{"type":"string","enum":["7d","30d","90d","365d"]}}],"responses":{"200":{"description":"The operations figures.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperationsAnalytics"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `range`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/analytics/search":{"get":{"operationId":"getAnalyticsSearch","summary":"Read search analytics over a range","description":"The numbers of the app's search view over `range` reporting days ending today: asset searches, those that found nothing, unique searchers, the same over the range before it, one point per day, and the top queries and top zero-result queries. For an OAuth token, its person needs membership of the org (no platform-admin bypass) and an asset's name is null when they may not read the asset; a key reads the whole org. 404 when the org does not have analytics, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["analytics:read"]},{"oauth2":["analytics:read"]}],"parameters":[{"name":"range","in":"query","required":false,"description":"How many reporting days, today included. Default `30d`.","schema":{"type":"string","enum":["7d","30d","90d","365d"]}}],"responses":{"200":{"description":"The search figures.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchAnalytics"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `range`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/members":{"get":{"operationId":"listMembers","summary":"List the org's members","description":"The people who are members of the org, by name, each with their email, their org roles and their teams. Every credential sees emails: members see each other's in the app. For an OAuth token, its person needs membership of the org (no platform-admin bypass); a key reads the whole org. 404 when the org does not have organization settings, and for an OAuth token whose person is not a member.","security":[{"apiKey":["org:read"]},{"oauth2":["org:read"]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Case-insensitive substring of the name or the email.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of members.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/channels":{"get":{"operationId":"listChannels","summary":"List the org's playout channels","description":"The org's playout channels as the DAM stores them — mode, the service each airs, whether it records and where — by name. Never a stream key, an ingest key or a destination, for any credential. Not the live on-air state: reading never calls the playout engine; that status is served once the orchestration tier owns the channel's convergence loop. Poll with `updated_after` (exclusive, millisecond). For an OAuth token, its person needs membership of the org (no platform-admin bypass); a key reads the whole org. 404 when the org does not have playout, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["channels:read"]},{"oauth2":["channels:read"]}],"parameters":[{"name":"updated_after","in":"query","required":false,"description":"Only channels changed strictly after this instant (ISO 8601 with offset), compared to the millisecond.","schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"limit","in":"query","required":false,"description":"Page size, default 50. Values above 100 are treated as 100.","schema":{"type":"integer","minimum":1,"maximum":9007199254740991}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page, with the other parameters unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of channels.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation — a bad `updated_after`, `limit` or `cursor` (`errors[].path` names it).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/channels/{id}":{"get":{"operationId":"getChannel","summary":"Get one playout channel","description":"One channel, in the list's shape. 404 when the org does not have playout, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["channels:read"]},{"oauth2":["channels:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The channel's id, from GET /api/v1/channels.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"If-None-Match","in":"header","required":false,"description":"An ETag from a previous response; 304 if unchanged.","schema":{"type":"string"}}],"responses":{"200":{"description":"The channel.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"304":{"description":"Not modified — the ETag in If-None-Match is current."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/channels/{id}/start":{"post":{"operationId":"startChannel","summary":"Start a playout channel (guarded)","description":"A guarded action (ADR 0081): it puts a service on air. The app's own start runs through the playout engine: the stored configuration is pushed, the channel started, then the on-air graphic's schedule pushed (a graphic that fails leaves the channel on air without it). Only a `strict` channel starts through the engine; a relay channel is 409. **An API key's start happens at once**: 200 with the Channel — as the DAM stores it: the answer carries no engine status (read the audit entry, or the app). **An OAuth token's does not**: 202 with a Confirmation naming the channel and the service; once its person confirms it in impartire it runs as them. Its person must be an org admin (the app's verb; no platform-admin bypass). Audited: a `channel.started` event with the engine's state after the call. 404 when the org does not have playout, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["channels:control"]},{"oauth2":["channels:control"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The channel's id, from GET /api/v1/channels.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"An API key's start: the channel as the DAM stores it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"202":{"description":"An OAuth token's start, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person is not an org admin.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — a relay channel; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"idempotency-mismatch (an OAuth token may not send Idempotency-Key).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"502":{"description":"playout-unavailable — the engine did not start the channel; nothing changed on air.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/channels/{id}/stop":{"post":{"operationId":"stopChannel","summary":"Stop a playout channel (guarded)","description":"A guarded action (ADR 0081): it takes a service off air. The app's own stop runs through the playout engine. Only a `strict` channel stops through the engine; a relay channel is 409. **An API key's stop happens at once**: 200 with the Channel — as the DAM stores it: the answer carries no engine status (read the audit entry, or the app). **An OAuth token's does not**: 202 with a Confirmation naming the channel and the service; once its person confirms it in impartire it runs as them. Its person must be an org admin (the app's verb; no platform-admin bypass). Audited: a `channel.stopped` event with the engine's state after the call. 404 when the org does not have playout, and for an OAuth token whose person is not a member of the org.","security":[{"apiKey":["channels:control"]},{"oauth2":["channels:control"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The channel's id, from GET /api/v1/channels.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Makes a retry safe: the same key and request within 24 hours replays the first response. 1–255 characters.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"An API key's stop: the channel as the DAM stores it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}},"headers":{"ETag":{"description":"Strong validator: `\"<v>.<fp>\"`; `v` is `updated_at` in microseconds, `fp` moves with anything else the body shows (a name it references).","schema":{"type":"string"}}}},"202":{"description":"An OAuth token's stop, waiting for its person to confirm it in impartire.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}},"headers":{"Location":{"description":"The confirmation's URL: poll it.","schema":{"type":"string"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — the token's person is not an org admin.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"conflict — a relay channel; confirmation-pending; or idempotency-in-flight.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"idempotency-mismatch (an OAuth token may not send Idempotency-Key).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"502":{"description":"playout-unavailable — the engine did not stop the channel; nothing changed on air.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/confirmations/{id}":{"get":{"operationId":"getConfirmation","summary":"Read a guarded action's confirmation","description":"A guarded action asked for with an OAuth token does not run: it answers 202 with a Confirmation and a Location here, and its person confirms or declines it in impartire at `confirm_url` within 15 minutes. Poll this until `status` is `executed` (then `result` is the action's answer, or `problem` why it failed) or `declined`. Any scope; readable only by the OAuth client and person that asked for it — another token's confirmation, a malformed id, and every API key (a key acts at once, so it never has one) are 404.","security":[{"oauth2":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The confirmation's id, from the 202 that created it (also its Location).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The confirmation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Confirmation"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"confirmation-expired — nobody decided within 15 minutes; the action did not run and never will.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/tags":{"get":{"operationId":"listAssetTags","summary":"List the tags on an asset","description":"Every version of an asset shows the same tags; the asset's ETag moves when its tags change. At most 500, ordered by the tag's normalized name; no cursor.","security":[{"apiKey":["assets:read"]},{"oauth2":["assets:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The asset's tags.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagLinkList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"addAssetTags","summary":"Add tags to an asset","description":"Each item is `{ name }` — the org's tag of that name, created as an org tag when there is none — or `{ id }` of an existing tag (the only way to add a team tag). A tag already on the asset stays as it was, so the call is safe to repeat: no Idempotency-Key, no If-Match. Answers the asset's whole tag list after. An OAuth token's person needs edit on the asset.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTagsRequest"}}}},"responses":{"200":{"description":"The asset's tags after.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagLinkList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may see the asset but lacks edit on the asset.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (`tags`: 1–50 items, each `{ name }` or `{ id }`; a name that is empty or over 64 characters), or unknown-tag.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/assets/{id}/tags/{tag_id}":{"delete":{"operationId":"removeAssetTag","summary":"Remove a tag from an asset","description":"Takes the tag off the asset; the tag stays in the org's list. 404 when the asset does not carry it, so a second DELETE is a 404.","security":[{"apiKey":["assets:write"]},{"oauth2":["assets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The asset's id: its current version's id or its root id (an older version's id is not found).","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"tag_id","in":"path","required":true,"description":"The tag's id, from GET …/tags.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Removed."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person lacks edit on the asset.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/projects/{id}/tags":{"get":{"operationId":"listProjectTags","summary":"List the tags on a project","description":"A project's own tags: its sub-projects and assets do not inherit them. At most 500, ordered by the tag's normalized name; no cursor.","security":[{"apiKey":["projects:read"]},{"oauth2":["projects:read"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"The project's tags.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagLinkList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope — the key lacks a required scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"addProjectTags","summary":"Add tags to a project","description":"Each item is `{ name }` — the org's tag of that name, created as an org tag when there is none — or `{ id }` of an existing tag (the only way to add a team tag). A tag already on the project stays as it was, so the call is safe to repeat: no Idempotency-Key, no If-Match. Answers the project's whole tag list after. An OAuth token's person needs update on the project.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTagsRequest"}}}},"responses":{"200":{"description":"The project's tags after.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagLinkList"}}}},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person may see the project but lacks update on the project.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"validation (`tags`: 1–50 items, each `{ name }` or `{ id }`; a name that is empty or over 64 characters), or unknown-tag.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/projects/{id}/tags/{tag_id}":{"delete":{"operationId":"removeProjectTag","summary":"Remove a tag from a project","description":"Takes the tag off the project; the tag stays in the org's list. 404 when the project does not carry it, so a second DELETE is a 404.","security":[{"apiKey":["projects:write"]},{"oauth2":["projects:write"]}],"parameters":[{"name":"id","in":"path","required":true,"description":"The project's id, from GET /api/v1/projects.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"tag_id","in":"path","required":true,"description":"The tag's id, from GET …/tags.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"204":{"description":"Removed."},"401":{"description":"unauthenticated — no key, or an unknown, revoked or expired one.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"insufficient-scope, or insufficient-permission — an OAuth token's person lacks update on the project.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"not-found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"rate-limited — the key's request budget is spent; wait Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"internal.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"impk_<43 base64url characters>","description":"An org API key. Its scopes are listed per operation."},"oauth2":{"type":"oauth2","description":"An OAuth 2.1 access token acting as a signed-in person, who sees only what they may. Authorization code with PKCE (S256); public clients register themselves at /api/auth/oauth2/register (RFC 7591) or present a client metadata document URL as their client_id. Request the token for the resource /api/v1 (RFC 8707). Discovery: /.well-known/oauth-protected-resource/api/v1.","flows":{"authorizationCode":{"authorizationUrl":"https://impartire.com/api/auth/oauth2/authorize","tokenUrl":"https://impartire.com/api/auth/oauth2/token","refreshUrl":"https://impartire.com/api/auth/oauth2/token","scopes":{"assets:read":"Read asset types, assets and their files","assets:write":"Upload files, create, edit and delete assets (includes read)","projects:read":"List projects and their playlists","projects:write":"Create and edit projects; create, edit and delete their playlists (includes read)","tags:read":"List the org's tags","workflows:read":"List the workflows a run can be started from","runs:read":"Read workflow runs and their progress","runs:write":"Start workflow runs (includes read)","collections:read":"Read collections and their items","collections:write":"Create, edit and delete collections and their items (includes read)","records:read":"Read record types and records","records:write":"Create, edit and delete records (includes read)","review:read":"Read assets' review comments and clip markers","people:read":"Read the org's people and their credits","taxonomy:read":"Read the org's category taxonomy","audit:read":"Read the org's audit log: who changed what, and when","delivery:read":"Read delivery requirements, readiness, receipts, spec profiles and delivery targets","epg:read":"Read the EPG: services, schedules, formats and the transmission log","analytics:read":"Read consumption, operations and search analytics","org:read":"Read the org's members, with their email addresses, roles and teams","channels:read":"Read playout channels and their configuration (no stream keys)","review:write":"Add, resolve and delete review comments and clip markers (includes read)","runs:signal":"Cancel workflow runs (a key never approves, rejects, completes or skips a step)","delivery:write":"Deliver content against a delivery requirement and reject received deliveries (includes read)","schedules:write":"Create, change and remove programmes on the EPG schedule","channels:control":"Start and stop playout channels","access:write":"Grant and deny project access, bind teams to projects and move projects","sharing:write":"Create and revoke public share links to assets"}}}}},"schemas":{"Problem":{"type":"object","properties":{"type":{"type":"string","description":"A stable URL naming the problem: https://impartire.com/problems/<code>. Branch on this."},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"detail":{"type":"string","description":"What went wrong and what to do about it, written for the caller."},"instance":{"type":"string","description":"The request path."},"request_id":{"type":"string","description":"Also sent as the Request-Id header. Quote it when reporting a problem."},"errors":{"description":"On 422 validation: one entry per invalid field.","type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The field or parameter, as a dotted path."},"message":{"type":"string"}},"required":["path","message"],"additionalProperties":false}},"edit_seq":{"description":"On 412 precondition-failed: the resource's current edit_seq.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"etag":{"description":"On 412 precondition-failed for a project, a collection, a playlist or a schedule slot: its current ETag.","type":"string"},"item_id":{"description":"On 409 already-member: the existing item's id (in the collection or playlist).","type":"string"},"schema_version":{"description":"On 409 type-changed: the asset type's current schema_version.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"confirmation_id":{"description":"On 409 confirmation-pending: the confirmation already waiting for its person (GET /api/v1/confirmations/{id}).","type":"string"},"confirm_url":{"description":"On 409 confirmation-pending: where the person confirms or declines it, in impartire.","type":"string"}},"required":["type","title","status","detail","instance","request_id"],"additionalProperties":false,"description":"An RFC 9457 Problem Details object (application/problem+json)."},"AssetField":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"key":{"type":"string","description":"The key a value is stored under in an asset's `fields`."},"name":{"type":"string","description":"The field's label, as the app shows it."},"type":{"type":"string","description":"text | url (a string) · select (one option `value`) · multiselect (an array of option values) · date (YYYY-MM-DD) · datetime (epoch milliseconds) · number · reference (an id, or an array of ids when `multiple`). More may be added."},"required":{"type":"boolean","description":"Required for the asset to be ready (a workflow gate may wait on it). Not enforced on a write: an asset may be created empty and filled in later."},"multiple":{"type":"boolean","description":"For a reference field, whether the value is an array of ids."},"options":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"}},"required":["value","label"],"additionalProperties":false}},{"type":"null"}],"description":"For select and multiselect, the accepted values (store `value`; `label` is for display). Null for every other type."}},"required":["id","key","name","type","required","multiple","options"],"additionalProperties":false,"description":"A field an asset type defines — the validation contract for `fields` on create and update: a declared key must hold a value of its type (a 422 names the key otherwise); keys the type does not declare are stored unvalidated."},"FileSlot":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":["string","null"]},"media_type":{"type":"string","description":"video | image | audio | document | subtitle"},"accept_extensions":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Accepted file extensions, or null for any of the media type."},"multiple":{"type":"boolean","description":"Whether the slot holds several files."}},"required":["id","name","media_type","accept_extensions","multiple"],"additionalProperties":false,"description":"A slot on an asset type that a file is attached to."},"AssetType":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"kind":{"type":"string","const":"asset"},"fields":{"type":"array","items":{"$ref":"#/components/schemas/AssetField"},"description":"The type's live field definitions, in the app's form order. Deprecated fields, and for an OAuth token the fields its person may not read, are left out."},"file_slots":{"type":"array","items":{"$ref":"#/components/schemas/FileSlot"}}},"required":["id","name","kind","fields","file_slots"],"additionalProperties":false,"description":"An asset type the org can create assets of, with its field definitions and live file slots."},"AssetTypeList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AssetType"}},"next_cursor":{"description":"Always null: the list is returned whole.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"ProjectRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"Project":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"description":{"type":["string","null"]},"parent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"visibility":{"type":"string","description":"open | closed | private"},"project_type":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The project's type (the org's project types: production, season, campaign…), or null if untyped."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"When its name, description or type last changed."}},"required":["id","name","description","parent_id","visibility","project_type","created_at","updated_at"],"additionalProperties":false},"ProjectList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"AssetFile":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slot":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The slot a caller's file was attached to; null for a file the pipeline derived."},"role":{"description":"null for a file attached to a slot; for a derived file, what the pipeline made: proxy, thumbnail, captions, conformed (more may be added).","type":["string","null"]},"media_type":{"type":"string"},"mime_type":{"type":["string","null"]},"extension":{"type":["string","null"]},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"uploaded_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"root_file_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The file's version chain: the id of its first version. Every version of the file shares it; GET /assets/{id}/files/{file_id} lists the chain."},"version_note":{"description":"Why this version was added, as its uploader wrote it; null when none was given.","type":["string","null"]},"uploaded_by":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The person who added this version ({ id: their principal id, name }). Null for a file the pipeline derived and for one added with an API key (every key of an org acts as one service principal, so the key is not recoverable from the file)."}},"required":["id","slot","role","media_type","mime_type","extension","size_bytes","version","uploaded_at","root_file_id","version_note","uploaded_by"],"additionalProperties":false,"description":"A current file of the asset: one attached to a slot, or one the pipeline derived from it. GET /assets/{id}/files/{file_id}/download signs a URL for its bytes."},"RunStep":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The template step's id (of the template version the run is pinned to)."},"name":{"type":"string"},"status":{"type":"string","description":"pending | in_progress | submitted | approved | completed | failed | skipped | incident (more may be added)."}},"required":["id","name","status"],"additionalProperties":false,"description":"One step of a run, in the template's gate order."},"Run":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"workflow":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false,"description":"The template version the run is pinned to (any version's id names its template in GET /api/v1/workflows/{id}). `name` is null when the run is `private`."},"asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false,"description":"The asset the run is about. `name` is null for an OAuth token whose person can no longer read the asset (a run they started)."},"status":{"type":"string","enum":["active","completed","cancelled","failed"]},"private":{"type":"boolean","description":"True when the run's template is private to a team the token's person is not in: the run's existence, status, team and times are shown, its workflow name, steps, current step, incident and params are not (always false for an API key)."},"team":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The team that owns the run, snapshotted from its template at start; null for an unowned run."},"parent_run_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"For a sub-workflow run, the run that started it."},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Moves on every change of state — poll on it with GET /api/v1/runs?updated_after=."},"completed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"started_via":{"type":"string","description":"api (started through this API) | manual (in the app) | trigger (by an arrival trigger, e.g. an upload). More may be added."},"current_step":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"status":{"type":"string"},"awaiting":{"anyOf":[{"type":"string","enum":["approval","completion","automation"]},{"type":"null"}],"description":"What the step waits on: `approval` (a person's verdict), `completion` (a person marking it done), `automation` (the pipeline — an automated step, a gate or a sub-workflow); null while it is parked on an incident."}},"required":["id","name","status","awaiting"],"additionalProperties":false},{"type":"null"}],"description":"The first open step at the run's current gate, while the run is active; null otherwise."},"steps":{"type":"array","items":{"$ref":"#/components/schemas/RunStep"}},"incident":{"anyOf":[{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false},{"type":"null"}],"description":"Set while an active run is parked on a step that failed and waits for an operator to retry it or fail the run (in the app)."},"params":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"The run's launch parameters, as validated against the template's param_schema."}},"required":["id","workflow","asset","status","private","team","parent_run_id","started_at","updated_at","completed_at","started_via","current_step","steps","incident","params"],"additionalProperties":false,"description":"A workflow run on an asset — one the API started, a person started in the app, or an upload set off."},"Asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"project":{"$ref":"#/components/schemas/ProjectRef"},"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Field values keyed by field key, as defined by the asset type."},"external_ref":{"description":"The caller's own id for this asset, as given at creation.","type":["string","null"]},"lifecycle_phase":{"type":"string","enum":["draft","ingested","verified","delivered"]},"edit_seq":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Increments on every change to name, fields, type or project. Also the ETag."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"files":{"type":"array","items":{"$ref":"#/components/schemas/AssetFile"}},"runs":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"description":"The newest runs started against this asset, newest first, at most 10."}},"required":["id","name","type","project","fields","external_ref","lifecycle_phase","edit_seq","created_at","updated_at","files","runs"],"additionalProperties":false},"AssetSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"project":{"$ref":"#/components/schemas/ProjectRef"},"external_ref":{"description":"The caller's own id for this asset, as given at creation.","type":["string","null"]},"lifecycle_phase":{"type":"string","enum":["draft","ingested","verified","delivered"]},"edit_seq":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Increments on every change to name, fields, type or project."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","type","project","external_ref","lifecycle_phase","edit_seq","created_at","updated_at"],"additionalProperties":false,"description":"An asset as a list shows it: the Asset without fields, files and runs. GET /api/v1/assets/{id} has the rest."},"AssetSummaryList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AssetSummary"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Me":{"type":"object","properties":{"authority":{"type":"string","enum":["org","user"],"description":"`org`: an org API key — its scopes, org-wide. `user`: an OAuth access token acting for one person — its scopes AND that person's own permissions, so it sees what they see and does what they may do."},"org":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The org this credential acts in."},"credential_class":{"type":"string","enum":["standard","guarded"],"description":"`guarded` when the credential holds any guarded scope (runs:signal, delivery:write, schedules:write, channels:control, access:write, sharing:write); `standard` otherwise. A guarded key must expire within 90 days and acts at once. With a guarded token, each guarded action waits for its person to confirm it in impartire."},"key":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"},"description":"What this key may do. `<resource>:write` includes `<resource>:read`."},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"When the key stops working, or null if it does not expire."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","scopes","expires_at","created_at"],"additionalProperties":false},{"type":"null"}],"description":"The API key, for `authority: org`; null for a token."},"user":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}],"description":"The person a token acts for, for `authority: user`; null for a key."},"client_id":{"description":"The OAuth client acting for the person (a URL for a client that published a metadata document); null for a key.","type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"},"description":"What this credential may do. `<resource>:write` includes `<resource>:read`."},"rate_limit":{"type":"object","properties":{"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Requests allowed per window, per credential. Enforced approximately (per edge location, eventually consistent): a burst can exceed it before the first 429."},"window_seconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["limit","window_seconds"],"additionalProperties":false}},"required":["authority","org","credential_class","key","user","client_id","scopes","rate_limit"],"additionalProperties":false,"description":"Who is calling: the credential, its org, its authority, its scopes and its request budget."},"DownloadUrl":{"type":"object","properties":{"url":{"type":"string","description":"A presigned GET for the file's bytes. Do not store it: it stops working at expires_at."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"When url stops working (5 minutes after issue). Ask again for a fresh one."},"filename":{"type":"string","description":"The stored object's file name."},"content_type":{"type":["string","null"]},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["url","expires_at","filename","content_type","size_bytes"],"additionalProperties":false,"description":"A short-lived URL for one file's bytes."},"Upload":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"upload_url":{"description":"PUT the file's bytes here, with `headers`. Null for a multipart upload: its parts' URLs come from `multipart.parts_url`.","type":["string","null"]},"method":{"type":"string","enum":["PUT","MULTIPART"],"description":"PUT: one PUT to upload_url. MULTIPART: parts, see `multipart`."},"headers":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},{"type":"null"}],"description":"Headers the PUT must send. Null for a multipart upload (a part's PUT needs none)."},"url_expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"When upload_url stops accepting a new PUT (15 minutes). Null for a multipart upload: each part URL carries its own expiry."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"When the upload must be used by (24 hours)."},"max_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","const":"pending"},"multipart":{"anyOf":[{"$ref":"#/components/schemas/UploadMultipart"},{"type":"null"}],"description":"Set for a multipart upload; null for a single PUT."}},"required":["upload_id","upload_url","method","headers","url_expires_at","expires_at","max_bytes","status","multipart"],"additionalProperties":false},"UploadStatus":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["pending","landed","consumed","expired"],"description":"pending: no bytes yet (for a multipart upload: not completed yet). landed: the bytes are in storage, ready for POST /api/v1/assets or POST /api/v1/assets/{id}/files. consumed: an asset was created from it, or it was attached to one (asset_id). expired: past expires_at, or aborted."},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"asset_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Set when consumed."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"multipart":{"anyOf":[{"$ref":"#/components/schemas/UploadMultipart"},{"type":"null"}],"description":"Set for a multipart upload; null for a single PUT."}},"required":["upload_id","status","size_bytes","asset_id","expires_at","multipart"],"additionalProperties":false},"Workflow":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The template's current version. Pass it as `workflow_id` to POST /api/v1/runs."},"name":{"type":"string"},"description":{"type":["string","null"]},"target_asset_type":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The asset type the template was built for (advisory: a run may be started on any asset)."},"action_type":{"description":"The media action the template runs, when it is a one-action template (e.g. transcode, captions); null for a multi-step process.","type":["string","null"]},"param_schema":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["reference","reference[]","enum","enum[]","string","number","boolean"]},"required":{"type":"boolean"},"label":{"type":"string"},"ref":{"description":"For a reference: what the value is an id of — broadcast_spec_profiles, delivery_requirements, asset_types (the org's), asset_files, video_editor_sequences (the run's asset's).","type":"string"},"media_type":{"description":"For a reference to asset_files: the media type the file must have.","type":"string"},"values":{"description":"For enum / enum[]: the accepted values.","type":"array","items":{"type":"string"}}},"required":["type"],"additionalProperties":false}},{"type":"null"}],"description":"The launch parameters `params` on POST /api/v1/runs is validated against, keyed by name; null when the template takes none."},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"When the template (its current version) last changed — poll on it with GET /api/v1/workflows?updated_after=."}},"required":["id","name","description","target_asset_type","action_type","param_schema","updated_at"],"additionalProperties":false,"description":"A workflow template a run can be started from."},"WorkflowList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Workflow"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"RunList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Run"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Tag":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The tag's id — what DELETE …/tags/{tag_id} and `{ id }` on POST …/tags take."},"name":{"type":"string","description":"The tag as first typed. Tags are matched by a normalized form: case, extra spaces and invisible characters are ignored."},"scope":{"type":"string","enum":["org","team"],"description":"`org`: the whole org's. `team`: private to one team (an OAuth token sees it only when its person is in the team or an org admin)."},"team":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The owning team, for a team tag; null for an org tag."},"usage_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many assets and projects carry the tag, across the org."}},"required":["id","name","scope","team","usage_count"],"additionalProperties":false,"description":"A tag of the org."},"TagList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"TagLink":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The tag's id — what DELETE …/tags/{tag_id} and `{ id }` on POST …/tags take."},"name":{"type":"string","description":"The tag as first typed. Tags are matched by a normalized form: case, extra spaces and invisible characters are ignored."},"scope":{"type":"string","enum":["org","team"],"description":"`org`: the whole org's. `team`: private to one team (an OAuth token sees it only when its person is in the team or an org admin)."},"team":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The owning team, for a team tag; null for an org tag."},"usage_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many assets and projects carry the tag, across the org."},"source":{"type":"string","enum":["user","generated"],"description":"`user`: a person or an API credential added it. `generated`: applied from a generated summary."},"added_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","scope","team","usage_count","source","added_at"],"additionalProperties":false,"description":"A tag on an asset or a project."},"TagLinkList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TagLink"},"description":"Ordered by the tag's normalized name. At most 500."},"next_cursor":{"description":"Always null: the list is returned whole (at most 500).","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"VideoInfo":{"type":"object","properties":{"duration_seconds":{"type":["number","null"]},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"codec":{"description":"The video codec, as the probe names it (h264, prores, …).","type":["string","null"]},"frame_rate":{"type":["number","null"]},"audio_codec":{"description":"The codec of the file's interleaved audio, if any.","type":["string","null"]},"audio_sample_rate":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"integrated_loudness":{"description":"Integrated loudness of the interleaved audio, LUFS (EBU R128).","type":["number","null"]},"color_primaries":{"type":["string","null"]},"color_transfer":{"type":["string","null"]}},"required":["duration_seconds","width","height","codec","frame_rate","audio_codec","audio_sample_rate","integrated_loudness","color_primaries","color_transfer"],"additionalProperties":false,"description":"What the pipeline measured about a video file. Any field may be null when the probe did not report it."},"AudioInfo":{"type":"object","properties":{"duration_seconds":{"type":["number","null"]},"codec":{"type":["string","null"]},"channels":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"sample_rate":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"bit_depth":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"integrated_loudness":{"description":"LUFS (EBU R128).","type":["number","null"]},"loudness_range":{"description":"LU (EBU R128 LRA).","type":["number","null"]}},"required":["duration_seconds","codec","channels","sample_rate","bit_depth","integrated_loudness","loudness_range"],"additionalProperties":false,"description":"What the pipeline measured about a stand-alone audio file (a stem). Any field may be null when the probe did not report it."},"ImageInfo":{"type":"object","properties":{"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"color_space":{"type":["string","null"]},"bit_depth":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["width","height","color_space","bit_depth"],"additionalProperties":false,"description":"What the pipeline measured about a still image. Any field may be null when the probe did not report it."},"AssetFileDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slot":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The slot a caller's file was attached to; null for a file the pipeline derived."},"role":{"description":"null for a file attached to a slot; for a derived file, what the pipeline made: proxy, thumbnail, captions, conformed (more may be added).","type":["string","null"]},"media_type":{"type":"string"},"mime_type":{"type":["string","null"]},"extension":{"type":["string","null"]},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"uploaded_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"root_file_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The file's version chain: the id of its first version. Every version of the file shares it; GET /assets/{id}/files/{file_id} lists the chain."},"version_note":{"description":"Why this version was added, as its uploader wrote it; null when none was given.","type":["string","null"]},"uploaded_by":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The person who added this version ({ id: their principal id, name }). Null for a file the pipeline derived and for one added with an API key (every key of an org acts as one service principal, so the key is not recoverable from the file)."},"technical":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/VideoInfo"},{"$ref":"#/components/schemas/AudioInfo"},{"$ref":"#/components/schemas/ImageInfo"}]},{"type":"null"}],"description":"What the pipeline measured, by `media_type`: VideoInfo for video, AudioInfo for audio, ImageInfo for image. Null until the measure pass has run on the file, and always null for other media types (documents, subtitles)."}},"required":["id","slot","role","media_type","mime_type","extension","size_bytes","version","uploaded_at","root_file_id","version_note","uploaded_by","technical"],"additionalProperties":false,"description":"An AssetFile with its technical metadata. A derived file's `size_bytes` may be null (not every pipeline step reports it yet)."},"AssetFileList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AssetFileDetail"}},"next_cursor":{"description":"Always null: an asset's current files are few and are returned whole.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"FileVersion":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"is_current":{"type":"boolean"},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"uploaded_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"uploaded_by":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"As on AssetFile: the person, or null for the pipeline and for an API key."},"version_note":{"type":["string","null"]}},"required":["id","version","is_current","size_bytes","uploaded_at","uploaded_by","version_note"],"additionalProperties":false,"description":"One version in a file's chain. Download it with GET /assets/{id}/files/{id}/download."},"AssetFileVersions":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"slot":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The slot a caller's file was attached to; null for a file the pipeline derived."},"role":{"description":"null for a file attached to a slot; for a derived file, what the pipeline made: proxy, thumbnail, captions, conformed (more may be added).","type":["string","null"]},"media_type":{"type":"string"},"mime_type":{"type":["string","null"]},"extension":{"type":["string","null"]},"size_bytes":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"uploaded_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"root_file_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The file's version chain: the id of its first version. Every version of the file shares it; GET /assets/{id}/files/{file_id} lists the chain."},"version_note":{"description":"Why this version was added, as its uploader wrote it; null when none was given.","type":["string","null"]},"uploaded_by":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The person who added this version ({ id: their principal id, name }). Null for a file the pipeline derived and for one added with an API key (every key of an org acts as one service principal, so the key is not recoverable from the file)."},"technical":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/VideoInfo"},{"$ref":"#/components/schemas/AudioInfo"},{"$ref":"#/components/schemas/ImageInfo"}]},{"type":"null"}],"description":"What the pipeline measured, by `media_type`: VideoInfo for video, AudioInfo for audio, ImageInfo for image. Null until the measure pass has run on the file, and always null for other media types (documents, subtitles)."},"is_current":{"type":"boolean","description":"Whether this is the chain's current version. Any version's id can be read and downloaded."},"versions":{"type":"array","items":{"$ref":"#/components/schemas/FileVersion"},"description":"Every version in the file's chain, newest first (current or not). Chains are short; returned whole."}},"required":["id","slot","role","media_type","mime_type","extension","size_bytes","version","uploaded_at","root_file_id","version_note","uploaded_by","technical","is_current","versions"],"additionalProperties":false,"description":"One file of an asset — any version — with its technical metadata and its whole version chain."},"UploadMultipart":{"type":"object","properties":{"part_size_bytes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Every part is exactly this size except the last, which is the remainder. Chosen by the server: at least 8 MiB, a whole number of MiB, at most 10 000 parts."},"part_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many parts: ceil(size_bytes / part_size_bytes). Part numbers run 1..part_count; part n is bytes (n-1)·part_size_bytes onward."},"parts_url":{"type":"string","description":"Where to sign the parts' upload URLs (POST, `{ part_numbers }`)."}},"required":["part_size_bytes","part_count","parts_url"],"additionalProperties":false,"description":"How a multipart upload is cut into parts."},"UploadPartUrl":{"type":"object","properties":{"part_number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"url":{"type":"string","description":"PUT exactly this part's bytes here, with no extra headers; keep the response's ETag header for POST …/complete."},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"When url stops accepting a new PUT (15 minutes). Sign the part again for a fresh one."}},"required":["part_number","url","expires_at"],"additionalProperties":false},"UploadPartUrlList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UploadPartUrl"},"description":"One per requested part number, in the order asked."}},"required":["data"],"additionalProperties":false},"Collection":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"description":{"type":["string","null"]},"project":{"anyOf":[{"$ref":"#/components/schemas/ProjectRef"},{"type":"null"}],"description":"The project the collection is filed in — its permission parent: who may open the project may open the collection. Null only for an OAuth token whose person owns the collection but cannot open its project."},"parent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The collection this one is nested in (GET /collections/{id}/children lists a parent's children), or null for a top-level collection."},"status":{"type":"string","enum":["draft","published"],"description":"`draft` until published to consumers. Publishing and archiving are done in the app."},"allowed_type_ids":{"anyOf":[{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"type":"null"}],"description":"When set, only assets of these asset types (GET /api/v1/asset-types) may be added. Null or empty: any type."},"allowed_category_ids":{"anyOf":[{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"type":"null"}],"description":"When set, only assets assigned at least one of these org categories may be added. Null or empty: any."},"item_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many items the collection holds (GET /collections/{id}/items lists them)."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"When its name, description or constraints last changed. Adding, removing or reordering items does not move it (the ETag moves instead)."}},"required":["id","name","description","project","parent_id","status","allowed_type_ids","allowed_category_ids","item_count","created_at","updated_at"],"additionalProperties":false,"description":"A curated, ordered set of assets."},"CollectionList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"CollectionItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The item's id — what DELETE …/items/{item_id} and PUT …/items/order take."},"asset":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["id","name","type"],"additionalProperties":false},{"type":"null"}],"description":"The asset (its current version). Null when `restricted`."},"restricted":{"type":"boolean","description":"True for an OAuth token whose person may not read the asset: the item keeps its place and id (a curator can still move or remove it) but not the asset's identity. Always false for an API key."},"sort_order":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The item's position key; items are listed by it, ascending."},"added_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","asset","restricted","sort_order","added_at"],"additionalProperties":false,"description":"One item of a collection: an asset at a position."},"CollectionItemList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CollectionItem"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Playlist":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"project":{"description":"The project the playlist belongs to — its permission parent: who may open the project may open the playlist, who may update the project may change it.","$ref":"#/components/schemas/ProjectRef"},"name":{"type":"string"},"description":{"type":["string","null"]},"target_count":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"How many items the playlist is meant to hold (e.g. a season's episode count), or null. Advisory: nothing refuses an item past it."},"item_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many items it holds (GET /playlists/{id}/items lists them)."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"When its name, description or target_count last changed. Adding, removing or reordering items does not move it (the ETag moves instead)."}},"required":["id","project","name","description","target_count","item_count","created_at","updated_at"],"additionalProperties":false,"description":"An ordered, count-aware sequence of assets belonging to a project (e.g. a season's episodes)."},"PlaylistList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Playlist"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"PlaylistItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The item's id — what DELETE …/items/{item_id} and PUT …/items/order take."},"asset":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["id","name","type"],"additionalProperties":false},{"type":"null"}],"description":"The asset (its current version). Null when `restricted`."},"restricted":{"type":"boolean","description":"True for an OAuth token whose person may not read the asset (a playlist in an open project may hold material from a private one): the item keeps its place and id but not the asset's identity. Always false for an API key."},"sort_order":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The item's place in the list; items are listed by it, ascending."},"position":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"An optional editorial slot number (e.g. episode 3), independent of the list order."},"added_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","asset","restricted","sort_order","position","added_at"],"additionalProperties":false,"description":"One item of a playlist: an asset at a place in the list."},"PlaylistItemList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PlaylistItem"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"RecordField":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"key":{"type":"string","description":"The key a value is stored under in an asset's `fields`."},"name":{"type":"string","description":"The field's label, as the app shows it."},"type":{"type":"string","description":"text | url (a string) · select (one option `value`) · multiselect (an array of option values) · date (YYYY-MM-DD) · datetime (epoch milliseconds) · number · reference (an id, or an array of ids when `multiple`). More may be added."},"required":{"type":"boolean","description":"Required for the asset to be ready (a workflow gate may wait on it). Not enforced on a write: an asset may be created empty and filled in later."},"multiple":{"type":"boolean","description":"For a reference field, whether the value is an array of ids."},"options":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"}},"required":["value","label"],"additionalProperties":false}},{"type":"null"}],"description":"For select and multiselect, the accepted values (store `value`; `label` is for display). Null for every other type."},"reference_target":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["asset","record","project"],"description":"What the field points at: an asset, a record, or a project of the org."},"type_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"For `record`, the record type the target must be of (GET /api/v1/record-types); null otherwise."}},"required":["kind","type_id"],"additionalProperties":false},{"type":"null"}],"description":"For a `reference` field, its target. Null for every other type."}},"required":["id","key","name","type","required","multiple","options","reference_target"],"additionalProperties":false,"description":"A field a record type defines — the AssetField shape plus, for a `reference` field, the kind of thing it points at. The validation contract for `fields` on POST / PATCH /records: a declared key must hold a value of its type (a reference: the target's id, or an array of ids when `multiple`); keys the type does not declare are stored unvalidated."},"RecordType":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"kind":{"type":"string","const":"record"},"fields":{"type":"array","items":{"$ref":"#/components/schemas/RecordField"},"description":"The type's live field definitions, in the app's form order. Deprecated fields, and for an OAuth token the fields its person may not read, are left out."}},"required":["id","name","kind","fields"],"additionalProperties":false,"description":"A record type of the org (a custom object: a Product, a Contract, a Talent release) — the shape its records' `fields` follow."},"RecordTypeList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RecordType"}},"next_cursor":{"description":"Always null: the list is returned whole.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"RecordReference":{"type":"object","properties":{"field_key":{"type":"string","description":"The reference field the value is stored under in `fields`."},"record":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"description":"The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Set when the field points at a record."},"asset":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"description":"The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Set when the field points at an asset (by the id stored in `fields`)."},"project":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"description":"The target's name (a record's title; a sub-project's as `<parent> › <name>` when the parent is readable too). Null when the target is gone or — for an OAuth token — its person may not read it: the id is already in `fields`, the name is not disclosed.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Set when the field points at a project."}},"required":["field_key","record","asset","project"],"additionalProperties":false,"description":"One value of a reference field, resolved: exactly one of record, asset, project is set."},"Record":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"Its record type (GET /api/v1/record-types)."},"title":{"type":"string"},"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Field values keyed by field key, as defined by the record type. For an OAuth token, the fields its person may not read are left out."},"references":{"type":"array","items":{"$ref":"#/components/schemas/RecordReference"},"description":"Every value of the reference fields in `fields`, resolved to a name, in the type's field order then value order."},"project":{"anyOf":[{"$ref":"#/components/schemas/ProjectRef"},{"type":"null"}],"description":"A project the record is filed under, or null. Informational: records are org-wide, and who may read one does not depend on it."},"edit_seq":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Increments on every change to title, fields, type or project. The first part of the ETag; If-Match on PATCH compares it."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","type","title","fields","references","project","edit_seq","created_at","updated_at"],"additionalProperties":false,"description":"An instance of a record type: a title, a field bag and resolved references."},"RecordList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Record"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page. For an OAuth token a page may hold fewer than `limit` records (those its person may not read are left out) and still have a next page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"ReferencingRecord":{"type":"object","properties":{"record":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string","description":"The record's title."},"type":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["id","name","type"],"additionalProperties":false},"field_key":{"type":"string","description":"The record's reference field that points at the asset."},"field_name":{"type":"string","description":"That field's label, as the app shows it."}},"required":["record","field_key","field_name"],"additionalProperties":false,"description":"A record whose reference field points at the asset; a record that points at it through two fields appears twice."},"ReferencingRecordList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ReferencingRecord"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page. A page may hold fewer than `limit` entries (those the credential may not see are left out) and still have a next page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Comment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"body":{"type":"string"},"author":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Who wrote it: `id` is their principal in the org, `name` their display name. Null if the author's account is gone. A comment written with an org API key is authored by the org's API service principal, named `API`."},"timestamp_seconds":{"description":"The point in the media the comment is pinned to, in seconds from the start; null for a comment on the asset as a whole.","type":["number","null"]},"parent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The comment this one replies to, or null for a top-level comment. The list is flat: thread it by `parent_id`."},"resolved_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"When it was marked resolved, or null while open."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Moves when the body is edited or the comment is resolved or reopened."}},"required":["id","body","author","timestamp_seconds","parent_id","resolved_at","created_at","updated_at"],"additionalProperties":false,"description":"A review comment on an asset. Comments belong to the asset, not a version: every version shows the same ones."},"CommentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Marker":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"label":{"type":["string","null"]},"start_seconds":{"type":"number","description":"Where the range starts, in seconds from the start of the media."},"end_seconds":{"type":"number","description":"Where it ends; always greater than start_seconds."},"created_by":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Who marked it: `id` is their principal in the org, `name` their display name. Null if their account is gone. A marker made with an org API key names the org's API service principal, `API`."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"A marker is never edited (made or deleted, in the app or the API), so this equals created_at."}},"required":["id","label","start_seconds","end_seconds","created_by","created_at","updated_at"],"additionalProperties":false,"description":"A clip marker: a labelled time range on an asset (the app's clips). Markers belong to the asset, not a version."},"MarkerList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Marker"},"description":"Returned whole: the app allows at most 3 markers per asset."},"next_cursor":{"description":"Always null: the list is returned whole.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"LineageBoundary":{"type":"object","properties":{"org_name":{"description":"The other organisation's name.","type":["string","null"]},"role":{"type":"string","description":"The edge's relationship, e.g. `delivered`."},"receipt_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The delivery receipt that wrote the edge, when there is one."}},"required":["org_name","role","receipt_id"],"additionalProperties":false,"description":"Where the lineage leaves the org: nothing of the other org's asset or its graph is disclosed."},"LineageNode":{"type":"object","properties":{"asset":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The asset (its current version's id and name). Null for a boundary node, and — for an OAuth token — for an asset its person may not read (`restricted`)."},"version":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The asset's current version number; null for a boundary node."},"type":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The asset's type — kept on a restricted node (the envelope); null for a boundary node or an untyped asset."},"depth":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Steps from the asset asked about: 0 for `self`, 1 for a direct parent or child."},"relationship":{"description":"The edge's role (`derivation`, `delivered`…) by which the node was reached at its smallest depth; null for `self`.","type":["string","null"]},"restricted":{"type":"boolean","description":"True when the node's content is withheld: a boundary node, or an asset an OAuth token's person may not read. The node keeps its place so the chain has no hole."},"boundary":{"anyOf":[{"$ref":"#/components/schemas/LineageBoundary"},{"type":"null"}],"description":"Set when the edge here joins another org; the walk stops at it."}},"required":["asset","version","type","depth","relationship","restricted","boundary"],"additionalProperties":false,"description":"One asset in a lineage graph, or the sealed boundary where it leaves the org."},"Lineage":{"type":"object","properties":{"root_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset's root id (its first version's id)."},"self":{"description":"The asset asked about, at depth 0.","$ref":"#/components/schemas/LineageNode"},"ancestors":{"type":"array","items":{"$ref":"#/components/schemas/LineageNode"},"description":"What it derives from, nearest first (one node per asset, at its smallest depth), then any boundary met."},"descendants":{"type":"array","items":{"$ref":"#/components/schemas/LineageNode"},"description":"What derives from it, nearest first, likewise."}},"required":["root_id","self","ancestors","descendants"],"additionalProperties":false,"description":"An asset's derivation lineage: ancestors and descendants over the lineage graph, at most 64 steps each way, cycle-guarded. Returned whole."},"PlaybackCaption":{"type":"object","properties":{"language":{"description":"The track's BCP 47 language tag, or null when it is not recorded.","type":["string","null"]},"label":{"type":"string","description":"A label for a track menu: the language's own name, plus \" (auto-translated)\" or \" (auto-generated)\" for a machine-made track; else the slot's name or `Subtitles`."},"url":{"type":"string","description":"A presigned GET for the WebVTT file. Stops working at the descriptor's `expires_at`."},"kind":{"type":"string","const":"subtitles","description":"The `<track kind>` to use. Always `subtitles` today."}},"required":["language","label","url","kind"],"additionalProperties":false,"description":"One playable caption track (WebVTT only — a caption in another format is not listed)."},"PlaybackProxy":{"type":"object","properties":{"variant":{"type":"string","description":"The rendition's variant, e.g. `1080p`, `720p`."},"url":{"type":"string","description":"A presigned GET for the MP4. Stops working at the descriptor's `expires_at`."},"width":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Pixels, as measured; null until measured."},"height":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Pixels, as measured; null until measured."}},"required":["variant","url","width","height"],"additionalProperties":false,"description":"One progressive MP4 proxy rendition of the played file, tallest first."},"Playback":{"type":"object","properties":{"status":{"type":"string","enum":["ready","processing","none"],"description":"`ready`: the HLS ladder is packaged and `hls_url` plays it. `processing`: the ladder is being made — nothing else in the descriptor is set; ask again. `none`: there is no ladder to play — the asset has no video, its transcode failed or was never started, or its delivery cannot be played through the API yet."},"hls_url":{"description":"The HLS manifest (with its signed access token when the delivery is signed); set only when `status` is `ready`. Do not store it: fetch the descriptor again for a fresh one.","type":["string","null"]},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"The earliest moment a URL in this descriptor may stop working; null when it carries no URL. Re-fetch the descriptor before then rather than caching URLs."},"poster_url":{"description":"A presigned GET for the asset's poster still, when it has one.","type":["string","null"]},"duration_seconds":{"description":"The played file's measured duration; null until measured or when there is no video.","type":["number","null"]},"captions":{"type":"array","items":{"$ref":"#/components/schemas/PlaybackCaption"},"description":"Caption tracks, originals before machine translations, oldest first — the first is the default track."},"proxies":{"type":"array","items":{"$ref":"#/components/schemas/PlaybackProxy"},"description":"Progressive MP4 proxies derived from the played file, tallest first."}},"required":["status","hls_url","expires_at","poster_url","duration_seconds","captions","proxies"],"additionalProperties":false,"description":"What a player needs to play an asset's primary video: the HLS manifest, poster, caption tracks and proxies — every URL short-lived, never the original (the master is an export, not a read)."},"Person":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"bio":{"type":["string","null"]},"nationality":{"description":"As entered in the app (free text, e.g. `British`).","type":["string","null"]},"birth_date":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"YYYY-MM-DD, or null."},"credit_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many credits the person holds on live assets of the org — org-wide, whoever asks (as the app's people list counts)."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"Moves when the person is edited in the app."}},"required":["id","name","bio","nationality","birth_date","credit_count","created_at","updated_at"],"additionalProperties":false,"description":"A person (talent, crew, contributor) the org keeps a record of. Archived people are not served."},"PersonList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Person"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"AssetCredit":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The credit's id."},"person":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"role":{"description":"The role credited (`Director`, `Host`…), as entered in the app; null when none was given.","type":["string","null"]},"billing_order":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Billing position, lowest first; null when unset."}},"required":["id","person","role","billing_order"],"additionalProperties":false,"description":"One person credited on an asset. Credits belong to the asset, not a version."},"AssetCreditList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AssetCredit"},"description":"By billing_order (unset last), then the person's name. Returned whole, at most 500."},"next_cursor":{"description":"Always null: the list is returned whole.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"PersonCredit":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The credit's id."},"asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"type":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["id","name","type"],"additionalProperties":false,"description":"The credited asset (its current version) and its type."},"role":{"type":["string","null"]},"billing_order":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["id","asset","role","billing_order"],"additionalProperties":false,"description":"One credit a person holds, from the asset's side."},"PersonCreditList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PersonCredit"}},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Category":{"type":"object","properties":{"group":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The category group (a facet: Genre, Territory…)."},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"description":{"type":["string","null"]},"parent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The category this one sits under (one level deep at most), or null."},"is_system":{"type":"boolean","description":"A category the platform seeded; it cannot be deleted in the app."}},"required":["group","id","name","description","parent_id","is_system"],"additionalProperties":false,"description":"A category of the org's asset taxonomy: the managed vocabulary an asset is categorised with (filter with GET /api/v1/assets?category_id=)."},"CategoryList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Category"},"description":"By group (its order in the app, then name), then name. Returned whole, at most 1000."},"next_cursor":{"description":"Always null: the list is returned whole.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"AssetCategory":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The category's id (GET /api/v1/categories)."},"name":{"type":"string"},"group":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["id","name","group"],"additionalProperties":false,"description":"A category assigned to an asset."},"AssetCategoryList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AssetCategory"},"description":"By group name, then name. Returned whole."},"next_cursor":{"description":"Always null: the list is returned whole.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"AuditEntry":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"occurred_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"action":{"type":"string","enum":["created","updated","deleted","event"],"description":"`created`, `updated`, `deleted` — the change itself. `event` — what a change MEANT (an asset created through the API, a file attached, a legal hold placed), recorded beside the change in the same request: its `changes` are on the entry with the same `request_id`."},"resource":{"type":"object","properties":{"type":{"type":"string","description":"The kind of thing changed: `asset`, `file`, `project`, `collection`, `playlist`, `record`, `tag`, `tag_link`, `asset_type`, `field_definition`, `workflow`, `spec_profile`, `api_key`, `run`, `receipt`, `delivery_requirement`, `delivery_target`, `schedule_slot`, `service`, `channel`, `share_link`, `comment`, `marker`, `confirmation`, `other`. `other` is something the feed does not describe (its name and changes are withheld). More types may be added."},"id":{"type":"string","description":"The changed row's id (for an asset, the version's id)."},"name":{"description":"Its name where the feed knows it; null otherwise.","type":["string","null"]}},"required":["type","id","name"],"additionalProperties":false},"actor":{"type":"object","properties":{"kind":{"type":"string","enum":["user","api_key","oauth","system","orchestration","unknown"],"description":"`user` — a person in the app; `api_key` — an org API key; `oauth` — an app acting for a person; `system` — the platform itself (a migration or maintenance); `orchestration` — a workflow run; `unknown` — not recorded."},"id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The person's principal id (`user`, `oauth`), the key's id (`api_key`, when the entry records it), or the run's id (`orchestration`, GET /api/v1/runs/{id}); null otherwise."},"name":{"description":"The person's name, or the key's name.","type":["string","null"]},"client_id":{"description":"For `oauth`, the app's OAuth client_id when the entry records it.","type":["string","null"]}},"required":["kind","id","name","client_id"],"additionalProperties":false},"request_id":{"description":"Shared by every entry one request produced; filter by it to see a whole change.","type":["string","null"]},"event":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","description":"The event's kind, e.g. `api_asset_create`, `legal_hold`, `derivation`. More may be added."}},"required":["kind"],"additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"null"}],"description":"For an entry that records a semantic event: its kind and its public ids and names (which keys depend on the kind). Null otherwise."},"changes":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"A public field of the resource. `fields` (an asset's or a record's field values) reports the changed KEYS only."},"from":{"description":"The value before (null when created or unset); for `fields`, the changed keys that were present before."},"to":{"description":"The value after (null when deleted or cleared); for `fields`, the changed keys present after."}},"required":["field","from","to"],"additionalProperties":false},"description":"The public fields that changed. Empty for an `event`, for `other`, and when nothing public changed."}},"required":["id","occurred_at","action","resource","actor","request_id","event","changes"],"additionalProperties":false,"description":"One entry of the org's audit trail, projected: who changed what and when, naming the public fields that changed — never the stored row images."},"AuditEntryList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"},"description":"Newest first (by `occurred_at`, then id)."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"SpecProfileRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"revision":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The spec's revision: a published spec changes only by a new revision, which supersedes this one."}},"required":["id","name","revision"],"additionalProperties":false,"description":"A spec profile revision, by id, name and revision number. GET /api/v1/spec-profiles/{id} reads it whole."},"DeliveryRequirement":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"project":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The project the requirement covers, with every sub-project under it."},"client":{"description":"Who the content is owed to; null for an internal demand (a house standard).","type":["string","null"]},"target":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The delivery target the obligation is delivered to (GET /api/v1/delivery-targets); null for an internal demand or when the target is gone."},"spec_profile":{"anyOf":[{"$ref":"#/components/schemas/SpecProfileRef"},{"type":"null"}],"description":"The spec revision the content must meet, pinned when the requirement was made."},"status":{"type":"string","enum":["active","fulfilled","cancelled"],"description":"`active` — in force (readiness and the spec gate apply it); `fulfilled`; `cancelled`."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","project","client","target","spec_profile","status","created_at","updated_at"],"additionalProperties":false,"description":"A standing demand: content in a project's subtree must meet a spec profile, for a client, delivered to a target."},"DeliveryRequirementList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryRequirement"},"description":"In the requested sort (default `-updated_at`), ties broken by id."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"ReadinessFailure":{"type":"object","properties":{"field":{"type":"string","description":"The spec field the file fails, as the validator names it (e.g. `frame_rate`, `loudness`)."},"reason":{"type":"string","description":"What was measured and what the spec requires, in words."},"code":{"type":"string","description":"A stable code, e.g. `CONFORMANCE_FRAME_RATE`."},"severity":{"type":"string","enum":["error","warning"]},"correctability":{"type":"string","enum":["correct","transcode","reject"],"description":"`correct` — fixable in place; `transcode` — fixable by a conform transcode; `reject` — needs a new upload."}},"required":["field","reason","code","severity","correctability"],"additionalProperties":false},"ReadinessEntry":{"type":"object","properties":{"asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"An asset in the requirement's project subtree (its current version)."},"status":{"type":"string","enum":["passed","failed","indeterminate","pending"],"description":"`passed` — a file of the asset meets the spec (a conformed rendition counts); `failed` — measured and out of spec; `indeterminate` — measured, no failure, but a demanded value could not be measured; `pending` — nothing to judge yet (no deliverable file, not yet measured, or a conform in flight)."},"cell":{"type":"object","properties":{"failures":{"type":"array","items":{"$ref":"#/components/schemas/ReadinessFailure"},"description":"Why the asset fails the spec; empty unless `failed`."},"file":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The file the verdict is about ({ id, name: its filename }); null when the asset has no deliverable file."}},"required":["failures","file"],"additionalProperties":false}},"required":["asset","status","cell"],"additionalProperties":false},"DeliveryReadiness":{"type":"object","properties":{"requirement":{"$ref":"#/components/schemas/DeliveryRequirement"},"assets":{"type":"array","items":{"$ref":"#/components/schemas/ReadinessEntry"},"description":"By asset id. Paginated: an asset's verdict is computed for the page that lists it."},"next_cursor":{"description":"Pass as `cursor` to get the next page of assets; null means this is the last page.","type":["string","null"]}},"required":["requirement","assets","next_cursor"],"additionalProperties":false,"description":"Every asset in the requirement's project subtree against its spec, as the app's readiness matrix shows it."},"DeliveryReceipt":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"requirement":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The requirement the delivery fulfils ({ id, name: its client, or `Internal` for an internal demand }); null for a social delivery or when the requirement is gone."},"asset":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The asset delivered, by its root id (GET /api/v1/assets/{id} takes it); `name` is the delivered version's. Null when the asset is deleted (soft or hard)."},"file":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The file delivered ({ id, name: its filename }); null when not recorded."},"target":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The delivery target; null for a social delivery or when the target is gone."},"spec_profile":{"anyOf":[{"$ref":"#/components/schemas/SpecProfileRef"},{"type":"null"}],"description":"The spec revision the delivery was made against."},"client":{"type":"string","description":"Who it was delivered to (kept when the requirement is gone)."},"status":{"type":"string","enum":["pending","delivered","failed","rejected"],"description":"`pending` — in flight; `delivered`; `failed` (see `error`); `rejected` — the receiving org refused it (see `rejection_note`)."},"error":{"type":["string","null"]},"rejection_note":{"description":"Why the receiving org rejected the delivery.","type":["string","null"]},"attestation":{"anyOf":[{"type":"object","properties":{"verdict":{"type":"string","description":"The supplier's conformance verdict on the file at delivery time (`ready` or `conformed`)."},"sha256":{"description":"The delivered file's SHA-256 (lowercase hex) as it landed; null until it has.","type":["string","null"]}},"required":["verdict","sha256"],"additionalProperties":false},{"type":"null"}],"description":"For a delivery to another org on the platform: what the supplier attested. Null otherwise."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"delivered_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["id","requirement","asset","file","target","spec_profile","client","status","error","rejection_note","attestation","created_at","delivered_at"],"additionalProperties":false,"description":"One delivery attempt in the org's ledger. Append-only: a redelivery is a new receipt."},"DeliveryReceiptList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryReceipt"},"description":"Newest first (by `created_at`, then id)."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"InboundDelivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"supplier_org":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The org that delivered."},"asset_name":{"description":"The supplier's asset name.","type":["string","null"]},"spec_profile":{"anyOf":[{"$ref":"#/components/schemas/SpecProfileRef"},{"type":"null"}],"description":"Your spec revision it was delivered against."},"status":{"type":"string","enum":["pending","delivered","failed","rejected"]},"received":{"anyOf":[{"type":"object","properties":{"asset_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Your asset the delivery landed as (GET /api/v1/assets/{id})."},"file_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The landed primary file."},"sha256":{"description":"The landed primary file's SHA-256 (lowercase hex).","type":["string","null"]},"landed_at":{"description":"When it landed (ISO 8601).","type":["string","null"]},"redelivery":{"type":"boolean","description":"True when it landed as a new version of an asset an earlier delivery landed."}},"required":["asset_id","file_id","sha256","landed_at","redelivery"],"additionalProperties":false},{"type":"null"}],"description":"Where the delivery landed in your org; null until it has."},"rejection_note":{"description":"Why you rejected it, when you did.","type":["string","null"]},"error":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"delivered_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]}},"required":["id","supplier_org","asset_name","spec_profile","status","received","rejection_note","error","created_at","delivered_at"],"additionalProperties":false,"description":"A delivery another org made to yours through a supply link (the receiver's view of its receipt)."},"InboundDeliveryList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/InboundDelivery"},"description":"Newest first (by `created_at`, then id)."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"SpecProfile":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"revision":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"owner_org":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The org that wrote the spec."},"mine":{"type":"boolean","description":"True when your org owns it."},"status":{"type":"string","enum":["private","published","retired"],"description":"`private` — the owner's own, editable; `published` — offered to suppliers, immutable (it changes by a new revision); `retired` — still readable, no longer accepted for new requirements."},"supersedes_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The revision this one replaced."},"superseded_by_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The revision that replaced this one, when you can read it."},"effective_from":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"accepts_until":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"After this instant the spec is no longer accepted for new requirements."},"frame_rate":{"type":"string"},"drop_frame":{"type":"boolean"},"resolution":{"type":["string","null"]},"aspect_ratio":{"type":["string","null"]},"audio_config":{"type":["string","null"]},"color_space":{"type":["string","null"]},"hdr":{"type":["string","null"]},"closed_captions":{"type":["boolean","null"]},"description":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","revision","owner_org","mine","status","supersedes_id","superseded_by_id","effective_from","accepts_until","frame_rate","drop_frame","resolution","aspect_ratio","audio_config","color_space","hdr","closed_captions","description","created_at","updated_at"],"additionalProperties":false,"description":"A technical delivery spec your org may read: its own, one another org published to it, or one a requirement of yours pins."},"SpecProfileList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SpecProfile"},"description":"In the requested sort (default `name`), ties broken by id."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"DeliveryTarget":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"kind":{"type":"string","enum":["s3","org"],"description":"`s3` — an S3-compatible bucket outside the platform; `org` — another org on the platform, through a supply link."},"receiver_org":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"For `org`: the org it delivers to. Null for `s3`."},"transport_ready":{"type":"boolean","description":"Whether a delivery can be made to it now (an `s3` target whose transport is not attached yet cannot)."},"accepts_spec_profile_ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"The specs it accepts (GET /api/v1/spec-profiles/{id}): for `org`, the receiver's published specs your org may still pin."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","kind","receiver_org","transport_ready","accepts_spec_profile_ids","created_at"],"additionalProperties":false,"description":"Where the org delivers to. Never its transport configuration or credentials."},"DeliveryTargetList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryTarget"},"description":"Oldest first (by `created_at`, then id)."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Service":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"description":{"type":["string","null"]},"number":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The channel number viewers know it by, when it has one."},"color":{"type":"string","description":"The colour the app shows the service in (a CSS hex colour)."},"sort_order":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Its place in the app's list of services (ascending)."},"spec_profile":{"anyOf":[{"$ref":"#/components/schemas/SpecProfileRef"},{"type":"null"}],"description":"The transmission spec its programmes are judged against (GET /api/v1/spec-profiles/{id}); null when none is set."},"default_format":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The fallback clock (GET /api/v1/formats/{id}) for a day no bound format covers; null when none is set."},"formats":{"type":"array","items":{"type":"object","properties":{"format":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"A clock the service may use (GET /api/v1/formats/{id})."},"starts_on":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The first broadcast day it applies (YYYY-MM-DD); null — no start bound."},"ends_on":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The last broadcast day it applies (YYYY-MM-DD); null — no end bound."}},"required":["format","starts_on","ends_on"],"additionalProperties":false},"description":"The formats bound to the service, each with the days it applies, by `starts_on` (unbounded first), then format name."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","description","number","color","sort_order","spec_profile","default_format","formats","created_at","updated_at"],"additionalProperties":false,"description":"A linear broadcast service (an EPG channel): its brand, transmission spec and the clocks its schedule is built on."},"ServiceList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Service"},"description":"By sort_order, then creation, as the app lists them. Returned whole, at most 1000."},"next_cursor":{"description":"Always null: the list is returned whole.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"ScheduleSlot":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"service":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The service the programme airs on."},"title":{"type":"string"},"description":{"type":["string","null"]},"starts_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"ends_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"asset":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The asset scheduled, by its root id (GET /api/v1/assets/{id} takes it); `name` is the version picked when it was scheduled. Null for a rotation slot or when the asset is deleted or not in this org."},"file":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The file that airs ({ id, name: its filename }), pinned when the asset was scheduled so a later upload cannot change what airs; null when none is pinned, or the pinned file is not an asset file of this org."},"source":{"anyOf":[{"anyOf":[{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"description":"The project's or collection's name. Null — for an OAuth token — when its person may not read it (a project they cannot open; a collection outside the projects they can open, or not shared with them): the id is the slot's own data, the name is not disclosed.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false}},"required":["project"],"additionalProperties":false},{"type":"object","properties":{"collection":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"description":"The project's or collection's name. Null — for an OAuth token — when its person may not read it (a project they cannot open; a collection outside the projects they can open, or not shared with them): the id is the slot's own data, the name is not disclosed.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false}},"required":["collection"],"additionalProperties":false}]},{"type":"null"}],"description":"Where a rotation slot draws its programme from — `{ project }` or `{ collection }`; null for a slot with no source, or one whose source is deleted or not in this org."},"format":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The clock the slot was authored against (GET /api/v1/formats/{id}), frozen on the slot; null for a freeform slot."},"readiness":{"type":"string","enum":["pending","ready","not_ready","unknown"],"description":"Whether what is scheduled meets the service's transmission spec, as last evaluated (when the slot is made, when its asset or service changes, and when its file is measured — not when you read it): `ready` — it meets the spec, or the service has no spec; `not_ready` — it fails the spec; `pending` — nothing to judge yet (no asset or no file), or a value the spec demands could not be measured; `unknown` — the file is not measured yet."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","service","title","description","starts_at","ends_at","asset","file","source","format","readiness","created_at","updated_at"],"additionalProperties":false,"description":"A programme on a service's schedule: what airs, when, and whether it is ready to air."},"ScheduleSlotList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleSlot"},"description":"By `starts_at`, then id."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"TransmissionEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"service":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The service the event airs on."},"slot_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The schedule slot it is derived from (GET /api/v1/schedules/{id})."},"event_type":{"type":"string","enum":["primary","secondary"],"description":"`primary` — the programme itself, one per slot; `secondary` — a break or an ID inside it, from the slot's format."},"secondary_kind":{"anyOf":[{"type":"string","enum":["break","noncommercial_break","id"]},{"type":"null"}],"description":"For a secondary event, the format element that produced it; null for a primary event."},"title":{"type":"string"},"starts_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"ends_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"file":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"For a primary event, the file that airs ({ id, name: its filename }); null for a break or an ID (their content is chosen later)."},"format":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The format the event was derived from."},"status":{"type":"string","enum":["planned","pushed","aired"],"description":"`planned` — derived from the schedule and re-derived when it changes; `pushed` — handed to playout; `aired`. Today every event is `planned`."}},"required":["id","service","slot_id","event_type","secondary_kind","title","starts_at","ends_at","file","format","status"],"additionalProperties":false,"description":"One event of the planned transmission log: a programme, or a break or an ID inside it."},"TransmissionLog":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TransmissionEvent"},"description":"By `starts_at`, then id."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false,"description":"The planned transmission log of a service in a window, derived from its schedule and the slots' formats. Not an as-run record."},"FormatElement":{"type":"object","properties":{"type":{"type":"string","enum":["segment","break","noncommercial_break","id"],"description":"`segment` — programme content; `break` — a commercial break; `noncommercial_break` — a promo or PSA break; `id` — a station ID."},"duration_ms":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How long the element runs, in milliseconds."}},"required":["type","duration_ms"],"additionalProperties":false,"description":"One element of a clock: what runs, and for how long."},"Format":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"description":{"type":["string","null"]},"elements":{"type":"array","items":{"$ref":"#/components/schemas/FormatElement"},"description":"The clock, in running order, as stored: elements run back to back from a slot's start, and the slot's length is their sum. In the transmission log a slot's breaks and IDs are these elements offset from its start (cut at its end)."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","description","elements","created_at","updated_at"],"additionalProperties":false,"description":"A broadcast format (a clock): the structure of a programme slot — its segments, breaks and IDs."},"FormatList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Format"},"description":"By name, then id."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"AnalyticsTotals":{"type":"object","properties":{"total_views":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Views: a surface that renders the asset was opened (once per session and asset)."},"unique_viewers":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Distinct viewers over the whole range — exact, not a sum of daily uniques."},"total_playback_ms":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Milliseconds of playback watched."},"total_downloads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Downloads: the bytes were taken."}},"required":["total_views","unique_viewers","total_playback_ms","total_downloads"],"additionalProperties":false,"description":"Consumption totals over a range."},"ConsumptionAnalytics":{"type":"object","properties":{"range":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first reporting day of the range (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last reporting day of the range (YYYY-MM-DD), today included."}},"required":["from","to"],"additionalProperties":false},"reporting_day":{"type":"object","properties":{"timezone":{"type":"string","description":"The org's reporting-day time zone (IANA)."},"day_start_hour":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The hour (0–23, in that zone) a reporting day starts — a broadcaster's day may start at 06:00."}},"required":["timezone","day_start_hour"],"additionalProperties":false,"description":"The org's reporting day: every day, range and bucket here is one of these, not a UTC calendar day."},"viewer_type":{"type":"string","enum":["all","internal","consumer","embed","api"],"description":"The audience the figures are filtered to (`all` — none). `by_viewer_type` ignores it."},"summary":{"$ref":"#/components/schemas/AnalyticsTotals"},"previous_period":{"type":"object","properties":{"total_views":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Views: a surface that renders the asset was opened (once per session and asset)."},"unique_viewers":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Distinct viewers over the whole range — exact, not a sum of daily uniques."},"total_playback_ms":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Milliseconds of playback watched."},"total_downloads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Downloads: the bytes were taken."},"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},"required":["total_views","unique_viewers","total_playback_ms","total_downloads","from","to"],"additionalProperties":false,"description":"The same totals over the range of equal length ending the day before `range.from`."},"series":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"views":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_viewers":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Distinct viewers that day."},"watched_ms":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"downloads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["day","views","unique_viewers","watched_ms","downloads"],"additionalProperties":false},"description":"One point per reporting day of the range, oldest first, zero-filled."},"top_assets":{"type":"array","items":{"type":"object","properties":{"asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset's current version id (GET /api/v1/assets/{id})."},"name":{"description":"The asset's name. Null — for an OAuth token — when its person may not read the asset: the figures are org figures every member sees on the dashboard; the name is not disclosed.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false},"views":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"downloads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["asset","views","downloads"],"additionalProperties":false},"description":"The ten most viewed assets of the range (every version of an asset counts toward it), most viewed first."},"by_device":{"type":"array","items":{"type":"object","properties":{"device_type":{"type":"string","description":"`desktop`, `mobile`, `tablet` or `unknown`."},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["device_type","count"],"additionalProperties":false},"description":"Views, downloads and playback sessions together, by device, largest first."},"by_viewer_type":{"type":"array","items":{"type":"object","properties":{"viewer_type":{"type":"string","description":"`internal` (a member), `consumer`, `embed` (a share link) or `api` (a developer-API download)."},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["viewer_type","count"],"additionalProperties":false},"description":"Views, downloads and playback sessions together, by audience, largest first — over every audience, whatever `viewer_type` is."}},"required":["range","reporting_day","viewer_type","summary","previous_period","series","top_assets","by_device","by_viewer_type"],"additionalProperties":false,"description":"How the org's content was consumed over a range: the numbers of the app's analytics dashboard."},"OperationsAnalytics":{"type":"object","properties":{"range":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first reporting day of the range (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last reporting day of the range (YYYY-MM-DD), today included."}},"required":["from","to"],"additionalProperties":false},"reporting_day":{"type":"object","properties":{"timezone":{"type":"string","description":"The org's reporting-day time zone (IANA)."},"day_start_hour":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The hour (0–23, in that zone) a reporting day starts — a broadcaster's day may start at 06:00."}},"required":["timezone","day_start_hour"],"additionalProperties":false,"description":"The org's reporting day: every day, range and bucket here is one of these, not a UTC calendar day."},"workflows":{"type":"object","properties":{"started":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Runs started in the range."},"completed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Runs that completed in the range (dated by when they ended)."},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"cancelled":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"active":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Runs open right now, whenever they started."},"duration_p50_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Median start-to-completion time of the runs completed in the range; null when none."},"duration_p90_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["started","completed","failed","cancelled","active","duration_p50_ms","duration_p90_ms"],"additionalProperties":false},"approvals":{"type":"object","properties":{"submitted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"approved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"latency_p50_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Median submit-to-approve time of the approvals given in the range; null when none."},"latency_p90_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["submitted","approved","latency_p50_ms","latency_p90_ms"],"additionalProperties":false},"incidents":{"type":"object","properties":{"active":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Run steps parked for an operator right now."}},"required":["active"],"additionalProperties":false},"deliveries":{"type":"object","properties":{"attempted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Deliveries attempted in the range; `delivered` and `failed` count how those turned out (the rest are pending)."},"delivered":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"success_rate":{"description":"delivered / attempted, 0–1; null when nothing was attempted.","type":["number","null"]},"latency_p50_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["attempted","delivered","failed","success_rate","latency_p50_ms"],"additionalProperties":false},"assets":{"type":"object","properties":{"created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time_to_first_approval_p50_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Median time from an asset's creation to its first approval, over first approvals given in the range."},"unconsumed":{"type":"object","properties":{"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Assets that existed when the range opened and were not viewed, downloaded or played during it."},"sample":{"type":"array","items":{"type":"object","properties":{"asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset's current version id (GET /api/v1/assets/{id})."},"name":{"description":"The asset's name. Null — for an OAuth token — when its person may not read the asset: the figures are org figures every member sees on the dashboard; the name is not disclosed.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["asset","created_at"],"additionalProperties":false},"description":"Up to ten of them, newest first."}},"required":["count","sample"],"additionalProperties":false}},"required":["created","time_to_first_approval_p50_ms","unconsumed"],"additionalProperties":false},"series":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"workflows_completed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"deliveries_delivered":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["day","workflows_completed","deliveries_delivered"],"additionalProperties":false},"description":"One point per reporting day of the range, oldest first, zero-filled."}},"required":["range","reporting_day","workflows","approvals","incidents","deliveries","assets","series"],"additionalProperties":false,"description":"How the DAM was operated over a range — runs, approvals, incidents, deliveries, assets: the numbers of the app's operations view."},"SearchTotals":{"type":"object","properties":{"searches":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"zero_result_searches":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_searchers":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["searches","zero_result_searches","unique_searchers"],"additionalProperties":false,"description":"Asset-search totals over a range."},"SearchAnalytics":{"type":"object","properties":{"range":{"type":"object","properties":{"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first reporting day of the range (YYYY-MM-DD)."},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The last reporting day of the range (YYYY-MM-DD), today included."}},"required":["from","to"],"additionalProperties":false},"reporting_day":{"type":"object","properties":{"timezone":{"type":"string","description":"The org's reporting-day time zone (IANA)."},"day_start_hour":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The hour (0–23, in that zone) a reporting day starts — a broadcaster's day may start at 06:00."}},"required":["timezone","day_start_hour"],"additionalProperties":false,"description":"The org's reporting day: every day, range and bucket here is one of these, not a UTC calendar day."},"summary":{"$ref":"#/components/schemas/SearchTotals"},"previous_period":{"type":"object","properties":{"searches":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"zero_result_searches":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unique_searchers":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"from":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"to":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},"required":["searches","zero_result_searches","unique_searchers","from","to"],"additionalProperties":false,"description":"The same totals over the range of equal length ending the day before `range.from`."},"series":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"searches":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"zero_results":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["day","searches","zero_results"],"additionalProperties":false},"description":"One point per reporting day, oldest first, zero-filled."},"top_queries":{"type":"array","items":{"type":"object","properties":{"query":{"type":"string"},"searches":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"avg_results":{"type":"number","description":"Mean result count, one decimal."}},"required":["query","searches","avg_results"],"additionalProperties":false},"description":"The 20 most frequent queries."},"zero_result_queries":{"type":"array","items":{"type":"object","properties":{"query":{"type":"string"},"searches":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["query","searches"],"additionalProperties":false},"description":"The 20 most frequent queries that found nothing."}},"required":["range","reporting_day","summary","previous_period","series","top_queries","zero_result_queries"],"additionalProperties":false,"description":"What people searched the asset library for, and did not find, over a range: the numbers of the app's search view."},"Member":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The member's principal id in this org."},"name":{"type":"string"},"email":{"type":"string","description":"Served to every credential: members see each other's email in the app."},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"description":"The org roles assigned to the member, by name."},"teams":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"description":"The teams the member belongs to (archived teams left out), by name."},"joined_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"When the member joined the org."}},"required":["id","name","email","roles","teams","joined_at"],"additionalProperties":false,"description":"A person who is a member of the org."},"MemberList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Member"},"description":"By name, then id."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Channel":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"mode":{"type":"string","enum":["strict","relay"],"description":"`strict` — a scheduled playlist the playout engine plays out; `relay` — a live feed restreamed to platforms."},"service":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The broadcast service (EPG channel, GET /api/v1/services/{id}) the channel airs; null when none is linked."},"recording":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["live_input"],"description":"What is recorded: `live_input` — a relay channel's incoming live feed, kept as a lossless master and registered as an asset."},"project":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"description":"Null — for an OAuth token — when its person may not read the project.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The project recordings are filed into; null when none is set or it is no longer a live project of the org (they file into the org's Unfiled project)."}},"required":["kind","project"],"additionalProperties":false},{"type":"null"}],"description":"Whether the channel records, and where the recordings go; null when it does not record."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","name","mode","service","recording","created_at","updated_at"],"additionalProperties":false,"description":"A playout channel's configuration as the DAM stores it — not its live on-air state, never a stream key or destination."},"ChannelList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Channel"},"description":"By name, then id."},"next_cursor":{"description":"Pass as `cursor` to get the next page; null means this is the last page.","type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false},"Confirmation":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["pending","confirmed","declined","expired","executed"],"description":"pending: waiting for the person to confirm or decline it in impartire (at `confirm_url`). confirmed: they confirmed and the action is running — poll again. executed: it ran; `result` holds its answer, or `problem` why it failed. declined: they said no; it will never run. expired: nobody decided within 15 minutes; it will never run (GET /api/v1/confirmations/{id} answers 410 confirmation-expired instead of this body; the person still sees it in impartire)."},"action":{"type":"string","description":"The guarded action, e.g. `run.signal`."},"resource":{"type":"object","properties":{"type":{"type":"string","description":"The kind of resource the action is on, e.g. `run`."},"id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"name":{"type":"string","description":"The resource as the person was shown it when the action was asked for."}},"required":["type","id","name"],"additionalProperties":false},"summary":{"type":"string","description":"The action in words, as the person reads it on the confirmation page."},"client_id":{"type":"string","description":"The OAuth client that asked."},"confirm_url":{"type":"string","description":"Where the person confirms or declines it. Show it to them; the API cannot confirm."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"15 minutes after it was asked for. A pending confirmation past it is expired."},"decided_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"When the person confirmed or declined it, or when it expired; null while pending."},"result":{"description":"When executed and the action succeeded: the action's answer (what the endpoint would have returned with a key). Null otherwise."},"problem":{"anyOf":[{"$ref":"#/components/schemas/Problem"},{"type":"null"}],"description":"When executed and the action failed: the Problem it failed with. Null otherwise."}},"required":["id","status","action","resource","summary","client_id","confirm_url","created_at","expires_at","decided_at","result","problem"],"additionalProperties":false,"description":"A guarded action an OAuth token asked for, waiting for its person to confirm it in impartire (ADR 0081). A guarded endpoint answers 202 with this and a Location; poll it until `status` is executed, declined or expired."},"Delivery":{"type":"object","properties":{"run":{"$ref":"#/components/schemas/Run"},"receipt":{"$ref":"#/components/schemas/DeliveryReceipt"}},"required":["run","receipt"],"additionalProperties":false,"description":"A delivery that has started: `run` is the Deliver run that pushes the file (poll GET /api/v1/runs/{id} until its `status` leaves `active`), `receipt` its row in the org's ledger, `pending` until the push lands (`delivered`) or fails (`failed`) — re-read GET /api/v1/delivery-receipts/{id}."},"ProjectGrant":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The project."},"subject":{"type":"object","properties":{"type":{"type":"string","enum":["member","team","role"],"description":"member: one person (GET /api/v1/members). team: everyone in the team. role: everyone holding the role. A team's or role's grant follows its membership."},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The member's principal id, or the team's or role's id."},"name":{"description":"The member's name, or the team's or role's. Null when it is no longer in the org.","type":["string","null"]}},"required":["type","id","name"],"additionalProperties":false},"level":{"type":"string","enum":["viewer","asset_contributor","asset_purger","contributor","manager"],"description":"viewer: read the project and everything filed under it. contributor: edit the project too. manager: administer it, including who has access. asset_contributor: edit the assets filed under it WITHOUT reading the project. asset_purger: delete them, likewise."}},"required":["project","subject","level"],"additionalProperties":false,"description":"A project access grant: who, at which level."},"ProjectDeny":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The project."},"subject":{"type":"object","properties":{"type":{"type":"string","enum":["member","team","role"],"description":"member: one person (GET /api/v1/members). team: everyone in the team. role: everyone holding the role. A team's or role's grant follows its membership."},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The member's principal id, or the team's or role's id."},"name":{"description":"The member's name, or the team's or role's. Null when it is no longer in the org.","type":["string","null"]}},"required":["type","id","name"],"additionalProperties":false},"reason":{"type":"string"}},"required":["project","subject","reason"],"additionalProperties":false,"description":"A deny: the subject loses read (and everything above it) on the project and everything under it, whatever else grants it."},"ProductionLane":{"type":"object","properties":{"production":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The production (the project)."},"team":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"lane":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The team's lane on the production: a project the team owns, private to it, attached to the production without inheriting its audience."},"created":{"type":"boolean","description":"False when the team was already assigned (the lane is the existing one)."}},"required":["production","team","lane","created"],"additionalProperties":false,"description":"A team assigned to a production, and its lane."},"ShareLink":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The asset it shares (its current version's id and name)."},"has_password":{"type":"boolean"},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"When it stops working; null: never."},"expired":{"type":"boolean"},"allow_download":{"type":"boolean"},"clip_start_seconds":{"type":["number","null"]},"clip_end_seconds":{"type":["number","null"]},"view_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many times it was opened."},"created_by":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Who made it: a member, or `API` for a link made with an org API key. Null if their account is gone."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["id","asset","has_password","expires_at","expired","allow_download","clip_start_seconds","clip_end_seconds","view_count","created_by","created_at"],"additionalProperties":false,"description":"A public link to an asset. Never carries the link's URL or token: those are returned once, when it is created."},"CreatedShareLink":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false,"description":"The asset it shares (its current version's id and name)."},"has_password":{"type":"boolean"},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"When it stops working; null: never."},"expired":{"type":"boolean"},"allow_download":{"type":"boolean"},"clip_start_seconds":{"type":["number","null"]},"clip_end_seconds":{"type":["number","null"]},"view_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"How many times it was opened."},"created_by":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Who made it: a member, or `API` for a link made with an org API key. Null if their account is gone."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"url":{"type":"string","description":"The public URL — the token in it is the link's whole authority. Returned ONCE, here (and in the confirmation's `result` for an OAuth token); never listed again. Keep it as you would a password."}},"required":["id","asset","has_password","expires_at","expired","allow_download","clip_start_seconds","clip_end_seconds","view_count","created_by","created_at","url"],"additionalProperties":false,"description":"A share link just created, with its URL — the only time the URL is returned."},"ShareLinkList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ShareLink"}},"next_cursor":{"type":["string","null"]}},"required":["data","next_cursor"],"additionalProperties":false,"description":"A page of an asset's share links, newest first."},"CreateAssetRequest":{"type":"object","properties":{"type_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"An asset type from GET /api/v1/asset-types."},"project_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The project the asset is placed in, from GET /api/v1/projects. Required: an API caller always names its project."},"name":{"type":"string","minLength":1,"maxLength":500},"fields":{"description":"Field values keyed by field key, validated against the asset type.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"external_ref":{"description":"Your own id for this asset; returned on every read.","type":"string","minLength":1,"maxLength":255},"file":{"description":"Attach an uploaded file. Its slot's pipeline (proxy, captions, QC…) starts as for a browser upload.","type":"object","properties":{"upload_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"A landed upload this key created with POST /api/v1/uploads."},"slot_id":{"description":"The file slot (GET /api/v1/asset-types). Omit to use the type's one slot that matches the file's media type.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["upload_id"]}},"required":["type_id","project_id","name"]},"UpdateAssetRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"fields":{"description":"The asset's whole field bag, validated against its type: keys left out are removed (send back what GET returned, changed). Legacy `<key>__legacy` values are carried forward unless sent as null.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"project_id":{"description":"Move the asset to this project (GET /api/v1/projects).","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"external_ref":{"description":"Your own id for this asset; null clears it.","anyOf":[{"type":"string","minLength":1,"maxLength":255},{"type":"null"}]},"schema_version":{"description":"The asset type's schema_version your `fields` were built against. When they fail validation and the type has moved past it, the answer is 409 type-changed instead of 422.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"description":"At least one of name, fields, project_id, external_ref."},"CreateUploadRequest":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":255,"description":"The file's name; its extension is what slots match on."},"content_type":{"type":"string","minLength":1,"maxLength":255,"description":"The MIME type the PUT will send."},"size_bytes":{"type":"integer","minimum":1,"maximum":5497558138880,"description":"The exact size of the file. Required: a single PUT's URL is bound to it, and a multipart upload is checked against it when completed. At most 5 GiB for a single PUT, 5 TiB with `multipart`."},"multipart":{"description":"Upload in parts (required above 5 GiB, allowed from 5 MiB). The response's `multipart` gives the part size and count; sign the parts' URLs with POST /api/v1/uploads/{id}/parts, PUT each part, then POST /api/v1/uploads/{id}/complete. Default false: one PUT.","type":"boolean"}},"required":["filename","content_type","size_bytes"]},"StartRunRequest":{"type":"object","properties":{"workflow_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"A template from GET /api/v1/workflows."},"asset_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset to run it on (its current version's id or its root id; the run is on the current version)."},"params":{"description":"Launch parameters, validated against the template's `param_schema`.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["workflow_id","asset_id"]},"AddTagsRequest":{"type":"object","properties":{"tags":{"minItems":1,"maxItems":50,"type":"array","items":{"anyOf":[{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64,"description":"A tag name. The org's tag of that name is used, or created as an org tag if there is none."}},"required":["name"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"An existing tag (GET /api/v1/tags) — the only way to add a team tag."}},"required":["id"],"additionalProperties":false}]},"description":"1–50 tags, each `{ name }` or `{ id }`."}},"required":["tags"]},"CreateProjectRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"description":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"parent_id":{"description":"Create it as a sub-project of this project (GET /api/v1/projects). Omit for a root project (a production), which is born Closed: org members see it exists, admitted teams open it.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"project_type_id":{"description":"One of the org's project types. When the parent is typed too, the org's hierarchy rules must allow this type under the parent's (a root needs a rule allowing the type at the root); 422 invalid-hierarchy otherwise.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["name"]},"UpdateProjectRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"description":{"description":"null clears it.","anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"project_type_id":{"description":"Retype the project; null makes it untyped. The org's hierarchy rules must allow the type under its parent's type (or at the root) and above each sub-project's type; 422 invalid-hierarchy otherwise.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"description":"At least one of name, description, project_type_id. Moving a project and changing its visibility are not in v1."},"AttachFileRequest":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"A landed upload this credential created with POST /api/v1/uploads."},"slot_id":{"description":"The file slot (GET /api/v1/asset-types). Omit to use the slot of `replace_file_id`, or else the type's one slot that matches the file's media type.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"replace_file_id":{"description":"A current file of this asset (an id from `files`) to replace: the upload becomes the next version of that file's chain, and the old version is kept. Without it, a slot that holds one file gets a new version of that file, and a slot that holds several (`multiple`) gets a new file beside the others.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"version_note":{"description":"Why this version exists (\"re-grade per client note\"); shown in the file's history.","type":"string","minLength":1,"maxLength":1000}},"required":["upload_id"],"description":"Attach an uploaded file to an asset: a new file in a slot, or a new version of one."},"RestoreFileRequest":{"type":"object","properties":{"version_note":{"description":"Why the earlier version is coming back. Default: \"Restored v<n>\".","type":"string","minLength":1,"maxLength":1000}},"description":"The body is optional; an empty body restores with the default note."},"SignPartsRequest":{"type":"object","properties":{"part_numbers":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"integer","minimum":1,"maximum":10000},"description":"The parts to sign: 1 to 100 distinct part numbers, each from 1 to the upload's `multipart.part_count`. Sign in batches for more."}},"required":["part_numbers"]},"CompleteUploadRequest":{"type":"object","properties":{"parts":{"minItems":1,"maxItems":10000,"type":"array","items":{"type":"object","properties":{"part_number":{"type":"integer","minimum":1,"maximum":10000},"etag":{"type":"string","minLength":1,"maxLength":200,"description":"The ETag header the part's PUT answered with, quotes included or not."}},"required":["part_number","etag"]},"description":"Every part, once each: all `multipart.part_count` of them, in any order."}},"required":["parts"]},"CreateCollectionRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"description":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"project_id":{"description":"The project to file it in (GET /api/v1/projects) — its permission parent. Omit to file it in the org's Unfiled project, which every member can open.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"parent_id":{"description":"Nest it in this collection (GET /api/v1/collections). The nesting is for browsing only: who may open it is decided by its own project.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"allowed_type_ids":{"description":"Only assets of these types may be added (GET /api/v1/asset-types).","maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"allowed_category_ids":{"description":"Only assets assigned at least one of these org categories may be added.","maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["name"]},"UpdateCollectionRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"description":{"description":"null clears it.","anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"allowed_type_ids":{"description":"null or [] lifts the constraint. Items already in the collection stay.","anyOf":[{"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"type":"null"}]},"allowed_category_ids":{"description":"null or [] lifts the constraint. Items already in the collection stay.","anyOf":[{"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"type":"null"}]}},"additionalProperties":false,"description":"At least one of name, description, allowed_type_ids, allowed_category_ids. `status` is not settable: publishing and archiving are lifecycle acts done in the app. Moving a collection is not in v1."},"AddCollectionItemRequest":{"type":"object","properties":{"asset_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset to add (its current version's id or its root id; the item pins the current version). GET /api/v1/assets lists them."},"sort_order":{"description":"Its position key. Omit to append after the last item.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["asset_id"]},"ReorderCollectionItemsRequest":{"type":"object","properties":{"item_ids":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Every item id of the collection, each exactly once, in the new order (at most 1000). The items' sort_order becomes 0, 1, 2… in this order."}},"required":["item_ids"]},"CreatePlaylistRequest":{"type":"object","properties":{"project_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The project it belongs to (GET /api/v1/projects). A typed project's type must allow playlists."},"name":{"type":"string","minLength":1,"maxLength":500},"description":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"target_count":{"description":"How many items it is meant to hold; advisory.","anyOf":[{"type":"integer","minimum":0,"maximum":1000000},{"type":"null"}]}},"required":["project_id","name"]},"UpdatePlaylistRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"description":{"description":"null clears it.","anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"target_count":{"description":"null clears it.","anyOf":[{"type":"integer","minimum":0,"maximum":1000000},{"type":"null"}]}},"additionalProperties":false,"description":"At least one of name, description, target_count. Moving a playlist to another project is not in v1; an unknown field is a 422."},"AddPlaylistItemRequest":{"type":"object","properties":{"asset_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset to add (its current version's id or its root id; the item pins the current version). GET /api/v1/assets lists them."},"position":{"description":"An editorial slot number (e.g. episode 3). The item is appended to the list whatever its position.","anyOf":[{"type":"integer","minimum":0,"maximum":1000000},{"type":"null"}]}},"required":["asset_id"]},"ReorderPlaylistItemsRequest":{"type":"object","properties":{"item_ids":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Every item id of the playlist, each exactly once, in the new order (at most 1000). The items' sort_order becomes 0, 1, 2… in this order; position is untouched."}},"required":["item_ids"]},"CreateRecordRequest":{"type":"object","properties":{"type_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"A record type from GET /api/v1/record-types."},"title":{"type":"string","minLength":1,"maxLength":1000,"description":"Leading and trailing spaces are trimmed; it may not be blank."},"fields":{"description":"Field values keyed by field key, validated against the record type (a reference: the target's id, or an array of ids when `multiple`).","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"project_id":{"description":"File the record under this project (GET /api/v1/projects). Informational: it does not change who may read it.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["type_id","title"]},"UpdateRecordRequest":{"type":"object","properties":{"title":{"description":"Leading and trailing spaces are trimmed; it may not be blank.","type":"string","minLength":1,"maxLength":1000},"fields":{"description":"The record's whole field bag, validated against its type: keys left out are removed (send back what GET returned, changed). Legacy `<key>__legacy` values are carried forward unless sent as null. For an OAuth token, a field its person may not read is kept as it was.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"additionalProperties":false,"description":"At least one of title, fields. Changing a record's type or project is not in v1; an unknown field is a 422."},"CreateCommentRequest":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":10000,"description":"The comment's text. Trimmed; blank is refused."},"timestamp_seconds":{"description":"Pin it to this point in the media, in seconds from the start; omitted or null for a comment on the asset as a whole.","anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"parent_id":{"description":"Reply to this comment (one on the same asset, from GET /api/v1/assets/{id}/comments); omitted or null for a top-level comment.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["body"]},"UpdateCommentRequest":{"type":"object","properties":{"resolved":{"description":"true marks it resolved (now), false reopens it. Setting the state it already has still moves updated_at.","type":"boolean"},"body":{"description":"New text — the author's alone (for a key: comments the key's org wrote through the API).","type":"string","minLength":1,"maxLength":10000}},"description":"At least one of `resolved` and `body`."},"CreateMarkerRequest":{"type":"object","properties":{"start_seconds":{"type":"number","minimum":0,"description":"Where the range starts, in seconds from the start of the media."},"end_seconds":{"type":"number","minimum":0,"description":"Where it ends; must be greater than start_seconds."},"label":{"description":"A short label; omitted or null for none.","anyOf":[{"type":"string","maxLength":200},{"type":"null"}]}},"required":["start_seconds","end_seconds"]},"SignalRunRequest":{"type":"object","properties":{"kind":{"type":"string","enum":["approve","reject","complete","skip","cancel"],"description":"`approve` / `reject` an approval step, `complete` a manual step, `skip` a step (a director-or-above act; never an automated step), `cancel` the run. With an API key only `cancel` is allowed: the others attest to work and must name a person (an OAuth token, confirmed by them)."},"workflow_step_id":{"description":"The step (from the run's `steps`): required for approve, reject, complete and skip.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"output_asset_id":{"description":"For `complete` or `approve` of a step whose requirements need a deliverable: the asset that satisfies them (one of the org's, which the person may edit).","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"note":{"description":"A note for the run's record (a skip's reason).","type":"string","maxLength":2000}},"required":["kind"]},"DeliverRequest":{"type":"object","properties":{"asset_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset to deliver: its current version's id or its root id (the current version is delivered). It must be in the requirement's org; for an OAuth token, one its person may read."},"target_id":{"description":"Where to deliver it (GET /api/v1/delivery-targets). Omit to deliver to the requirement's own target.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"file_id":{"description":"The file to deliver: one of the asset's files whose verdict for the requirement's spec passes (GET /api/v1/delivery-requirements/{id}/readiness names it). Omit for the best passing file, a conformed rendition first.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["asset_id"]},"RejectDeliveryRequest":{"type":"object","properties":{"rejection_note":{"type":"string","minLength":1,"maxLength":2000,"description":"Why your org refuses the delivery. Required: the supplier reads it on their receipt."}},"required":["rejection_note"]},"CreateScheduleSlotRequest":{"type":"object","properties":{"service_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The service (EPG channel) it airs on, from GET /api/v1/services."},"title":{"type":"string","minLength":1,"maxLength":500},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"starts_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"ends_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","description":"After `starts_at`."},"asset_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset that airs: its current version's id or its root id (the current version is scheduled; `asset.id` from a slot is its root id). A live asset of this org. The file that airs is pinned when it is scheduled — `file_id`, or the asset's primary video."},{"type":"null"}]},"file_id":{"description":"Pin this file to air: a file of the asset (any of its versions). Needs `asset_id`. Omit to pin the asset's primary video.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"source_project_id":{"description":"A rotation slot's source: a live project of this org. Not with `source_collection_id`.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"source_collection_id":{"description":"A rotation slot's source: a live collection of this org, by its id or its root id. Not with `source_project_id`.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"format_id":{"description":"The clock the slot is authored against (GET /api/v1/formats), frozen on the slot.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"broadcast_day":{"description":"The broadcast day (YYYY-MM-DD) the slot belongs to, when it is not `starts_at`'s UTC date — a programme after midnight belongs to the day before. Stamped once; a change never re-stamps it.","type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},"required":["service_id","title","starts_at","ends_at"]},"UpdateScheduleSlotRequest":{"type":"object","properties":{"service_id":{"description":"Move it to another service of this org.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string","minLength":1,"maxLength":500},"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"starts_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"ends_at":{"description":"After `starts_at` (the new one, or the slot's).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"asset_id":{"description":"Another asset to air (its current version's id or its root id; the file is re-pinned), or null to make it a rotation slot.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The asset that airs: its current version's id or its root id (the current version is scheduled; `asset.id` from a slot is its root id). A live asset of this org. The file that airs is pinned when it is scheduled — `file_id`, or the asset's primary video."},{"type":"null"}]},"file_id":{"description":"Pin this file to air: a file of the scheduled asset (any of its versions) — the one `asset_id` names, or the slot's. On a slot whose asset is under legal hold, a change of the file is 409 `legal-hold`.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"source_project_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"source_collection_id":{"description":"By its id or its root id.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"format_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}}},"GrantProjectAccessRequest":{"type":"object","properties":{"subject_type":{"type":"string","enum":["member","team","role"],"description":"member: one person (GET /api/v1/members). team: everyone in the team. role: everyone holding the role. A team's or role's grant follows its membership."},"subject_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The member's principal id (GET /api/v1/members), or the team's or role's id — of this org."},"level":{"type":"string","enum":["viewer","asset_contributor","asset_purger","contributor","manager"],"description":"viewer: read the project and everything filed under it. contributor: edit the project too. manager: administer it, including who has access. asset_contributor: edit the assets filed under it WITHOUT reading the project. asset_purger: delete them, likewise."}},"required":["subject_type","subject_id","level"]},"DenyProjectAccessRequest":{"type":"object","properties":{"subject_type":{"type":"string","enum":["member","team","role"],"description":"member: one person (GET /api/v1/members). team: everyone in the team. role: everyone holding the role. A team's or role's grant follows its membership."},"subject_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"The member's principal id, or the team's or role's id — of this org. Not yourself."},"reason":{"type":"string","minLength":1,"maxLength":500,"description":"Why. Required: a deny is a reasoned, recorded act."}},"required":["subject_type","subject_id","reason"]},"BindProjectTeamRequest":{"type":"object","properties":{"team_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"A team of this org that is not archived."}},"required":["team_id"]},"MoveProjectRequest":{"type":"object","properties":{"parent_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The new parent project (GET /api/v1/projects), or null to make it a top-level project."}},"required":["parent_id"]},"CreateShareLinkRequest":{"type":"object","properties":{"expires_in_days":{"description":"The link stops working this many days from now (1–365). Null or omitted: it never expires.","anyOf":[{"type":"integer","minimum":1,"maximum":365},{"type":"null"}]},"password":{"description":"A password the viewer must enter. Stored salted and hashed, never readable again. Null or omitted: none.","anyOf":[{"type":"string","minLength":1,"maxLength":256},{"type":"null"}]},"allow_download":{"description":"Whether the viewer may download the video. Default false.","type":"boolean"},"clip_start_seconds":{"description":"Pin the link to a cut: its start, in seconds. Set with clip_end_seconds.","anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"clip_end_seconds":{"description":"The cut's end, in seconds; after clip_start_seconds.","anyOf":[{"type":"number","minimum":0},{"type":"null"}]}}}}}}