# Final Frame > Final Frame is a media supply chain platform for studios, distributors and platform operators. It maps incoming deliverables to per-destination delivery specs, then tracks, transforms, checks and fills the gaps, from first delivery to final archive. Every action is on an append-only audit trail. Rights in and rights out are held per work, and availability is computed, never guessed. Vocabulary: an Org is the customer and the isolation boundary. A Group is a node in its tree. A Project is one deal. A Title is the work. A Deliverable is one required output for one destination. A Work order is work raised where demand exceeds supply. ## Machine access - API reference (OpenAPI 3.1, generated from the running code): https://qa.app.final-frame.com/api/v1/openapi.json - Docs: https://qa.app.final-frame.com/docs - Authentication: Authorization: Bearer . Keys are minted under Organisation settings, Integrations, by an organisation admin, carry a chosen set of permissions (noun.verb, e.g. project.view) and belong to exactly one organisation. Personal keys are capped by their owner's live access. - MCP server (Streamable HTTP, stateless): https://qa.app.final-frame.com/api/mcp. Protected-resource metadata: https://qa.app.final-frame.com/.well-known/oauth-protected-resource. The same API key works as the bearer. - Every list is a page of at most 100 with a cursor (next_cursor). Every write needs an Idempotency-Key header and replays its first answer for a day. Errors are { error, message } with the standard status; a 403 names the missing scope in WWW-Authenticate. - Media never passes through the API: downloads are signed URLs that expire in fifteen minutes. ## Resources - https://qa.app.final-frame.com/api/v1/me: who is calling. - https://qa.app.final-frame.com/api/v1/projects: deals, newest first. One deal: /projects/{id}. Its rights: /projects/{id}/rights. Its titles: /projects/{id}/titles and /projects/{id}/titles/{titleId}?include=metadata,credits,certificates,companies&lang=en-GB. Its deliverables: /projects/{id}/deliverables (filters family, kind, status, presence=present|empty, titleId, language, territory; sort=family|status|dueDate|title; every row carries presence: what is on it), one row at /deliverables/{id}, a signed link at /deliverables/{id}/download, a data row's data at /deliverables/{id}/data. Put a file in: POST /deliverables/{id}/uploads (needs asset.upload), then /uploads/{sessionId}/parts for more signed part URLs and /uploads/{sessionId}/complete with the ETags; the bytes go straight to storage. Status, notes, due date: PATCH /deliverables/{id}. Editorial metadata per language: GET and PUT /projects/{id}/titles/{titleId}/metadata. Work orders: /projects/{id}/work-orders (GET, POST). Close-out: /projects/{id}/closeout. Action log: /projects/{id}/audit. - Everyday writes, each under the permission the product uses: POST /projects (project.create) and PATCH /projects/{id} (project.configure: name, references, client, dates, rights, licence, territories, deliverySpecIds). POST /projects/{id}/titles adds a title, season or episode; PATCH /projects/{id}/titles/{titleId} sets identifiers (EIDR, IMDb, TMDB, Wikidata, house ids) and facts; POST /projects/{id}/titles/bulk-edit writes one change across many titles. POST /projects/{id}/deliverables adds a placeholder. - https://qa.app.final-frame.com/api/v1/rights/holdings and https://qa.app.final-frame.com/api/v1/rights/restrictions: POST records rights held in a work, or what narrows them (holdback, clearance, talent, blackout); POST /{id}/revoke revokes one and keeps the record. Needs org.settings.edit. - https://qa.app.final-frame.com/api/v1/delivery-specs: the organisation's specs (GET, POST; PATCH /{id}). https://qa.app.final-frame.com/api/v1/industry-specs: the platforms' published specs; POST /{id}/duplicate copies one into the library. Changing the library needs org.settings.edit. - https://qa.app.final-frame.com/api/v1/rights/works: every work with what the organisation holds (owned, licensed in, mixed, not recorded) and, with ?territory=&from=&to=&rights=, a cell per right: available, available_non_exclusive, partial, licensed_exclusive, held_back, not_held, not_held_exclusively, not_recorded, assumed, unknown. One work: /rights/works/{identity}. One answer with reasons: /rights/availability?identity=&right=&territory=&from=&to=&match=cover|overlap|start_within|end_within. - https://qa.app.final-frame.com/api/v1/reference/rights: the rights taxonomy (116 codes in a tree; granting a node grants its descendants), the regions and their member countries. - https://qa.app.final-frame.com/api/v1/rights/works/{identity}/children: a show's seasons and episodes, each with its own position and cells (?season= for one season's episodes). Season identities are the show's plus #s2, episodes #s2e3; every rights endpoint accepts them. - https://qa.app.final-frame.com/api/v1/rights/map?right=svod: one right across every country: how many works are available there in the window, licensed out (shared or exclusively) and to whom, held back or not held; with ?identity= one work's state per country. ISO 3166-1 alpha-2 keys. - https://qa.app.final-frame.com/api/v1/rights/works/{identity}/windows: the work's release plan (theatrical, PVOD, EST, TVOD, physical, airline, hotel, Pay-1, Pay-2, free TV, AVOD, FAST; projected from a profile until written down). PUT replaces it; PUT .../release sets the release date, status and profile. - https://qa.app.final-frame.com/api/v1/cloud/connections: the organisation's own buckets (GCS, S3, Azure) the credential may browse; /cloud/connections/{id}/objects lists under a prefix; POST /cloud/imports copies one object into a deal, onto a placeholder when deliverableId is given. https://qa.app.final-frame.com/api/v1/bin: the organisation's asset bin, with uploads in parts and signed downloads; POST /projects/{id}/deliverables/{id}/attach puts a bin object or another placeholder's file on a placeholder. - https://qa.app.final-frame.com/api/v1/billing: the plan the organisation is on (subscription, seat fee, allowances, unit prices, marketplace fee), this month line by line with what is beyond the allowance, the projection, ninety days of daily cost by metric, and the invoices. Micros of the currency. Needs org.settings.edit. - https://qa.app.final-frame.com/api/v1/config: the organisation's set-up as one document (delivery specs, formats, metadata schema, taxonomies). GET exports; PUT applies by name and key and never deletes. The ff CLI wraps this as ff config export and ff config apply. ## Permissions member.view, member.invite, member.remove, member.role.assign, org.view, org.settings.edit, group.view, group.create, group.rename, group.delete, project.view, project.create, project.configure, project.archive, project.delete, project.handoff, project.end, asset.view, asset.upload, asset.download, job.view, job.create, qc.view, qc.execute, workorder.view, workorder.create, inbox.view, inbox.manage, integration.configure, audit.view ## Events (webhooks) asset.received, qc.passed, qc.failed, deliverable.status_changed, handoff.accepted, buyback.answered, workorder.created, rights.holding_recorded ## Environments QA: https://qa.app.final-frame.com (this host). Production is built when v1 is finished; keys and tokens never cross environments.