{"openapi":"3.1.0","info":{"title":"joma API","version":"1.0.0","description":"Manage your joma organization — your site's pages, your catalog, free-access grants and your customer list — from code or an AI tool. Every request needs your organization's API key: sign in → your organization → Developer Access. Guides: https://joma.film/developers","contact":{"email":"support@joma.film"},"termsOfService":"https://joma.film/terms"},"servers":[{"url":"https://joma.film/api/v1"}],"security":[{"apiKey":[]}],"tags":[{"name":"Context","description":"Start here."},{"name":"Pages","description":"Your site's pages and their sections. Edits stage as a draft until you publish."},{"name":"Site settings","description":"Branding, site-wide styles, redirects and hosted images."},{"name":"Entities","description":"Structured items (screenings, press quotes, …) your pages display."},{"name":"Films","description":"Your films."},{"name":"Series","description":"Series, seasons and episodes."},{"name":"Merch","description":"Your merchandise."},{"name":"Access grants","description":"Give people free access to a film."},{"name":"Customers","description":"Your customer list, for syncing into a mailing tool."}],"paths":{"/context":{"get":{"tags":["Context"],"summary":"Everything about your site in one call","operationId":"getContext","description":"Your branding, pages, catalog, entities, available section types and their content shapes, catalog bindings, customization options, and the platform rules your content must follow. Designed for AI tools: fetch this first.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"org":{"type":"object","additionalProperties":true,"description":"Name, curator code, domain and branding."},"site":{"type":"object","additionalProperties":true,"description":"Live URL, pages and site-wide styles."},"dashboard":{"type":"object","additionalProperties":true,"description":"Links into your dashboard."},"catalog":{"type":"object","additionalProperties":true,"description":"Your series, films (each with `editablePageKnobs`) and active merch."},"entities":{"type":"object","additionalProperties":true,"description":"Allowed entity types and what you have."},"bindings":{"type":"object","additionalProperties":true,"description":"Catalog bindings you can use in sections."},"sectionTypes":{"type":"array","items":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/SectionType"},"description":{"type":"string"},"contentShape":{"type":"string"}}}},"sectionFields":{"type":"object","additionalProperties":true},"customization":{"type":"object","additionalProperties":true,"description":"Navigation, text styles, newsletter and surface-color options with their current values."},"constraints":{"type":"object","additionalProperties":true,"description":"Platform rules your content must follow."}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}}},"/access/grants":{"get":{"tags":["Access grants"],"summary":"List free-access grants for a film","operationId":"listGrants","parameters":[{"name":"filmSlug","in":"query","required":true,"description":"Film slug.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by status.","schema":{"$ref":"#/components/schemas/GrantStatusFilter"}},{"name":"page","in":"query","required":false,"description":"Page number (default 1).","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","required":false,"description":"Results per page (default 50, max 200).","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"grants":{"type":"array","items":{"$ref":"#/components/schemas/Grant"}},"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}},"post":{"tags":["Access grants"],"summary":"Give someone free access to a film","operationId":"createGrant","description":"Emails the recipient a claim link unless `sendEmail` is false. Granting again to the same email refreshes the invite (200, `action: refreshed`); an already-claimed grant returns `action: already_accepted`. A daily limit applies.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"filmSlug":{"type":"string"},"expiresAt":{"type":["string","null"],"description":"Must be in the future. Omit or null for permanent access.","format":"date-time"},"sendEmail":{"type":"boolean","description":"Default true."},"note":{"type":"string","description":"Personal note included in the email."}},"required":["email","filmSlug"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"grant":{"$ref":"#/components/schemas/Grant"},"action":{"type":"string","description":"refreshed | already_accepted"},"emailSent":{"type":"boolean"},"message":{"type":"string"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"grant":{"$ref":"#/components/schemas/Grant"},"action":{"type":"string","description":"created"},"emailSent":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"409":{"$ref":"#/components/responses/Error409"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/access/grants/{id}":{"delete":{"tags":["Access grants"],"summary":"Revoke a pending grant","operationId":"revokeGrant","description":"Only unclaimed grants can be revoked; a claimed grant returns 409.","parameters":[{"name":"id","in":"path","required":true,"description":"Grant id.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","description":"revoked"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"409":{"$ref":"#/components/responses/Error409"},"429":{"$ref":"#/components/responses/Error429"}}}},"/customers/filmmaker":{"get":{"tags":["Customers"],"summary":"Customers who bought your films","operationId":"listFilmmakerCustomers","description":"Each record has `marketingOptOut`. Under the joma terms you must honor it: never include an opted-out customer in marketing. Re-sync at least daily and always overwrite consent from the latest value.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"customers":{"type":"array","items":{"$ref":"#/components/schemas/FilmmakerCustomer"}},"total":{"type":"integer"},"fetchedAt":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}}},"/customers/curator":{"get":{"tags":["Customers"],"summary":"Customers who bought through your curator link or code","operationId":"listCuratorCustomers","description":"Each record has `marketingOptOut`. Under the joma terms you must honor it: never include an opted-out customer in marketing. Re-sync at least daily and always overwrite consent from the latest value.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"customers":{"type":"array","items":{"$ref":"#/components/schemas/CuratorCustomer"}},"total":{"type":"integer"},"fetchedAt":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/pages":{"get":{"tags":["Pages"],"summary":"List your pages","operationId":"listPages","description":"Published and unpublished pages, with whether each has unpublished edits.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"pages":{"type":"array","items":{"$ref":"#/components/schemas/PageSummary"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}},"post":{"tags":["Pages"],"summary":"Create a page","operationId":"createPage","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"slug":{"type":"string","description":"Derived from the title if omitted."},"description":{"type":"string"},"isPublished":{"type":"boolean","description":"Default false."}},"required":["title"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"page":{"$ref":"#/components/schemas/Page"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"409":{"$ref":"#/components/responses/Error409"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/pages/{slug}":{"get":{"tags":["Pages"],"summary":"Get a page","operationId":"getPage","description":"Returns the live page plus any staged `draft`. `version` is the page's current version — pass it as `expectedVersion` when editing a section to avoid overwriting someone else's change.","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"page":{"$ref":"#/components/schemas/Page"},"version":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}},"put":{"tags":["Pages"],"summary":"Update page settings, publish or unpublish","operationId":"updatePage","description":"Edits are staged as a draft and go live when you publish (`isPublished: true`). Publishing checks every section first and returns 400 naming the section that can't go live.","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"page":{"$ref":"#/components/schemas/Page"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}},"delete":{"tags":["Pages"],"summary":"Delete a page","operationId":"deletePage","description":"A version is kept, so a deleted page can be restored (see /content/versions).","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/pages/{slug}/discard":{"post":{"tags":["Pages"],"summary":"Discard unpublished edits","operationId":"discardDraft","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/pages/{slug}/render":{"get":{"tags":["Pages"],"summary":"Render a page to HTML","operationId":"renderPage","description":"Server-rendered HTML of the page as it would appear (including unpublished edits), for checking your work. `status` is the render's own HTTP status.","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"},"status":{"type":"integer"},"html":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"},"502":{"$ref":"#/components/responses/Error502"}}}},"/content/pages/{slug}/sections":{"post":{"tags":["Pages"],"summary":"Add a section","operationId":"addSection","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SectionInput"},{"type":"object","properties":{"index":{"type":"integer","description":"Insert position. Default: append.","minimum":0}},"required":["content"]}]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"section":{"$ref":"#/components/schemas/Section"},"index":{"type":"integer"},"warnings":{"type":"array","items":{"type":"string"},"description":"Non-blocking notices (e.g. a section refers to a film that isn't available)."}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/pages/{slug}/sections/{index}":{"put":{"tags":["Pages"],"summary":"Edit a section","operationId":"updateSection","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}},{"name":"index","in":"path","required":true,"description":"0-based section position.","schema":{"type":"integer","minimum":0}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SectionInput"},{"type":"object","properties":{"expectedVersion":{"type":"integer","description":"The page `version` you last read. A mismatch returns 409."}}}]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"section":{"$ref":"#/components/schemas/Section"},"warnings":{"type":"array","items":{"type":"string"},"description":"Non-blocking notices (e.g. a section refers to a film that isn't available)."},"version":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"409":{"$ref":"#/components/responses/Error409"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}},"delete":{"tags":["Pages"],"summary":"Remove a section","operationId":"deleteSection","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}},{"name":"index","in":"path","required":true,"description":"0-based section position.","schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"$ref":"#/components/schemas/Section"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/pages/{slug}/sections/reorder":{"put":{"tags":["Pages"],"summary":"Reorder sections","operationId":"reorderSections","parameters":[{"name":"slug","in":"path","required":true,"description":"Page slug (e.g. `home`).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"order":{"type":"array","items":{"type":"integer"},"description":"Every current index exactly once, in the new order, e.g. [2, 0, 1]."}},"required":["order"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/SectionType"}}}}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/versions":{"get":{"tags":["Pages"],"summary":"List page versions","operationId":"listVersions","description":"Saved snapshots of your pages, newest first.","parameters":[{"name":"slug","in":"query","required":false,"description":"Only this page's versions.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Max results (1–200, default 50).","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"versions":{"type":"array","items":{"$ref":"#/components/schemas/PageVersion"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/versions/{id}/restore":{"post":{"tags":["Pages"],"summary":"Restore a page version","operationId":"restoreVersion","description":"The current state is saved as a version first. A deleted page comes back unpublished.","parameters":[{"name":"id","in":"path","required":true,"description":"Version id.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"page":{"$ref":"#/components/schemas/Page"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/settings":{"get":{"tags":["Site settings"],"summary":"Get organization settings and branding","operationId":"getSettings","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}},"put":{"tags":["Site settings"],"summary":"Update organization settings and branding","operationId":"updateSettings","description":"All-or-nothing: if any field is invalid, nothing is saved.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/styles":{"get":{"tags":["Site settings"],"summary":"Get site-wide CSS and scripts","operationId":"getStyles","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Styles"}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}},"put":{"tags":["Site settings"],"summary":"Update site-wide CSS and scripts","operationId":"updateStyles","description":"Applies to every page. CSS is sanitized. Scripts only run where joma has enabled them for your organization. Returns the saved values.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Styles"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Styles"}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/redirects":{"get":{"tags":["Site settings"],"summary":"List redirects","operationId":"listRedirects","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"redirects":{"type":"array","items":{"$ref":"#/components/schemas/Redirect"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}},"put":{"tags":["Site settings"],"summary":"Replace your redirects","operationId":"setRedirects","description":"Replaces the whole list (send [] to clear). Up to 500 entries; no duplicate `from`, no redirect chains, and nothing under /api.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"redirects":{"type":"array","items":{"$ref":"#/components/schemas/Redirect"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"redirects":{"type":"array","items":{"$ref":"#/components/schemas/Redirect"}}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/assets":{"post":{"tags":["Site settings"],"summary":"Import an image into joma-hosted storage","operationId":"importAsset","description":"Pass a public https image URL; get back a joma-hosted URL to use in your pages.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sourceUrl":{"type":"string","description":"Public https image URL."}},"required":["sourceUrl"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/entities":{"get":{"tags":["Entities"],"summary":"List entities of a type","operationId":"listEntities","description":"Screenings, press quotes and other structured items your pages can display.","parameters":[{"name":"type","in":"query","required":true,"description":"Entity type.","schema":{"$ref":"#/components/schemas/EntityType"}},{"name":"publishedOnly","in":"query","required":false,"description":"Pass `false` to include unpublished entities.","schema":{"type":"string","enum":["true","false"]}},{"name":"sort","in":"query","required":false,"description":"By sort order. Default `asc`.","schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"entities":{"type":"array","items":{"$ref":"#/components/schemas/Entity"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}},"post":{"tags":["Entities"],"summary":"Create an entity","operationId":"createEntity","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entityType":{"$ref":"#/components/schemas/EntityType"},"data":{"type":"object","additionalProperties":true},"sortOrder":{"type":"integer","description":"Default 0."},"isPublished":{"type":"boolean","description":"Default true."}},"required":["entityType","data"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"entity":{"$ref":"#/components/schemas/Entity"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/content/entities/{id}":{"put":{"tags":["Entities"],"summary":"Update an entity","operationId":"updateEntity","description":"`data` replaces the entity's data (it is not merged).","parameters":[{"name":"id","in":"path","required":true,"description":"Entity id.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entityType":{"$ref":"#/components/schemas/EntityType"},"data":{"type":"object","additionalProperties":true},"sortOrder":{"type":"integer"},"isPublished":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"entity":{"$ref":"#/components/schemas/Entity"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}},"delete":{"tags":["Entities"],"summary":"Delete an entity","operationId":"deleteEntity","parameters":[{"name":"id","in":"path","required":true,"description":"Entity id.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}}},"/catalog/films":{"get":{"tags":["Films"],"summary":"List your films","operationId":"listFilms","description":"Every film your organization owns, in any status.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"films":{"type":"array","items":{"$ref":"#/components/schemas/CatalogFilm"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}}},"/catalog/films/{slug}":{"get":{"tags":["Films"],"summary":"Get a film","operationId":"getFilm","description":"Includes the film's reviews and which page settings you may edit on it.","parameters":[{"name":"slug","in":"path","required":true,"description":"Film slug.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"film":{"$ref":"#/components/schemas/FilmDetail"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}},"patch":{"tags":["Films"],"summary":"Update a film's page and details","operationId":"updateFilm","description":"Descriptions, filmmaker bio, featured reviews, page display settings, section toggles, and episode placement. Pricing, availability, visibility and video are managed in the dashboard.","parameters":[{"name":"slug","in":"path","required":true,"description":"Film slug.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilmUpdate"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"film":{"$ref":"#/components/schemas/FilmDetail"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/catalog/series":{"get":{"tags":["Series"],"summary":"List your series","operationId":"listSeries","description":"Each series with its seasons and their episodes.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"series":{"type":"array","items":{"$ref":"#/components/schemas/SeriesTree"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}},"post":{"tags":["Series"],"summary":"Create a series","operationId":"createSeries","requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SeriesInput"},{"type":"object","properties":{},"required":["title"]}]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"series":{"$ref":"#/components/schemas/SeriesTree"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"409":{"$ref":"#/components/responses/Error409"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/catalog/series/{slug}":{"get":{"tags":["Series"],"summary":"Get a series","operationId":"getSeries","parameters":[{"name":"slug","in":"path","required":true,"description":"Series slug.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"series":{"$ref":"#/components/schemas/SeriesTree"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}},"patch":{"tags":["Series"],"summary":"Update a series","operationId":"updateSeries","description":"Partial update — send at least one field. Sending `slug` renames the series.","parameters":[{"name":"slug","in":"path","required":true,"description":"Series slug.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"series":{"$ref":"#/components/schemas/SeriesTree"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"409":{"$ref":"#/components/responses/Error409"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/catalog/series/{slug}/seasons":{"get":{"tags":["Series"],"summary":"List a series' seasons","operationId":"listSeasons","parameters":[{"name":"slug","in":"path","required":true,"description":"Series slug.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"seasons":{"type":"array","items":{"$ref":"#/components/schemas/CatalogSeason"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}},"post":{"tags":["Series"],"summary":"Create a season","operationId":"createSeason","description":"The season is created off sale. Its price, visibility and going on sale are set in the dashboard (the response's `dashboard` link).","parameters":[{"name":"slug","in":"path","required":true,"description":"Series slug.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"seasonNumber":{"type":"integer","description":"Defaults to the next number.","minimum":1},"seasonTitle":{"type":["string","null"],"maxLength":255}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"season":{"$ref":"#/components/schemas/CatalogSeason"},"note":{"type":"string"},"dashboard":{"type":"string","description":"Dashboard path for this season."}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"409":{"$ref":"#/components/responses/Error409"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/catalog/series/{slug}/seasons/{number}/episodes":{"get":{"tags":["Series"],"summary":"List a season's episodes","operationId":"listEpisodes","parameters":[{"name":"slug","in":"path","required":true,"description":"Series slug.","schema":{"type":"string"}},{"name":"number","in":"path","required":true,"description":"Season number.","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"episodes":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEpisode"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}},"post":{"tags":["Series"],"summary":"Add one of your films as an episode","operationId":"addEpisode","parameters":[{"name":"slug","in":"path","required":true,"description":"Series slug.","schema":{"type":"string"}},{"name":"number","in":"path","required":true,"description":"Season number.","schema":{"type":"integer","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filmSlug":{"type":"string"},"episodeAccess":{"type":"string","enum":["free","included","paid"],"description":"Default `included`. Making an episode `free` is a pricing change: set it in the dashboard. The API returns 403 for it."},"episodeNumber":{"type":"integer","description":"Defaults to the end of the season.","minimum":1}},"required":["filmSlug"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"episodes":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEpisode"}}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"403":{"$ref":"#/components/responses/Error403"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}},"put":{"tags":["Series"],"summary":"Reorder a season's episodes","operationId":"reorderEpisodes","parameters":[{"name":"slug","in":"path","required":true,"description":"Series slug.","schema":{"type":"string"}},{"name":"number","in":"path","required":true,"description":"Season number.","schema":{"type":"integer","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"order":{"type":"array","items":{"type":"string"},"description":"Every current episode's film slug, exactly once, in the new order."}},"required":["order"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"episodes":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEpisode"}}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/catalog/merch":{"get":{"tags":["Merch"],"summary":"List your merch","operationId":"listMerch","parameters":[{"name":"includeInactive","in":"query","required":false,"description":"Pass `true` to include inactive items.","schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"merch":{"type":"array","items":{"$ref":"#/components/schemas/MerchListItem"}}}}}}},"401":{"$ref":"#/components/responses/Error401"},"429":{"$ref":"#/components/responses/Error429"}}},"post":{"tags":["Merch"],"summary":"Create a merch item","operationId":"createMerch","requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/MerchInput"},{"type":"object","properties":{},"required":["name","price"]}]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"item":{"$ref":"#/components/schemas/MerchItem"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}}},"/catalog/merch/{id}":{"get":{"tags":["Merch"],"summary":"Get a merch item","operationId":"getMerch","parameters":[{"name":"id","in":"path","required":true,"description":"Merch item id.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"item":{"$ref":"#/components/schemas/MerchItem"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}},"patch":{"tags":["Merch"],"summary":"Update a merch item","operationId":"updateMerch","description":"Partial update — send only the fields to change.","parameters":[{"name":"id","in":"path","required":true,"description":"Merch item id.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"item":{"$ref":"#/components/schemas/MerchItem"}}}}}},"400":{"$ref":"#/components/responses/Error400"},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"413":{"$ref":"#/components/responses/Error413"},"429":{"$ref":"#/components/responses/Error429"}}},"delete":{"tags":["Merch"],"summary":"Delete a merch item","operationId":"deleteMerch","description":"An item that already appears on an order or bundle is deactivated instead of deleted (`softDeleted: true`).","parameters":[{"name":"id","in":"path","required":true,"description":"Merch item id.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"softDeleted":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Error401"},"404":{"$ref":"#/components/responses/Error404"},"429":{"$ref":"#/components/responses/Error429"}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Your organization's API key (starts with `joma_`), sent as `Authorization: Bearer <key>`."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable reason."}},"required":["error"]},"SectionType":{"type":"string","enum":["html","hero","text_block","merch_grid","film_card","film_grid","press_quotes","events","contact_form","embed","composition","press_article_list","newsletter_signup","form","earnings_calculator","custom"],"description":"`html` takes an HTML string. Every other type takes a structured object — GET /context lists each type's shape (`sectionTypes[].contentShape`)."},"Section":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/SectionType"},"name":{"type":"string","description":"Optional label for editors.","maxLength":80},"content":{"oneOf":[{"type":"string","description":"HTML (type `html`)."},{"type":"object","additionalProperties":true,"description":"Structured content (every other type)."}]},"styles":{"type":"string","description":"CSS scoped to this section."},"jomaBindings":{"type":"object","additionalProperties":true,"description":"Bindings to your catalog (see GET /context `bindings`)."}},"required":["id","type","content"]},"SectionInput":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/SectionType"},"content":{"oneOf":[{"type":"string"},{"type":"object","additionalProperties":true}]},"name":{"type":"string","maxLength":80},"styles":{"type":"string"},"jomaBindings":{"type":"object","additionalProperties":true}}},"Page":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"slug":{"type":"string"},"title":{"type":"string","description":"Live title."},"description":{"type":["string","null"]},"content":{"type":"object","properties":{"sections":{"type":"array","items":{"$ref":"#/components/schemas/Section"}},"navOverlay":{"type":"boolean"},"navBackground":{"type":"string","enum":["auto","light","dark"]}},"description":"Live (published) content."},"metadata":{"type":"object","properties":{"seoTitle":{"type":"string"},"seoDescription":{"type":"string"},"ogImage":{"type":"string"},"canonicalUrl":{"type":"string"},"noIndex":{"type":"boolean"}}},"isPublished":{"type":"boolean"},"showInNav":{"type":"boolean"},"navOrder":{"type":"integer"},"navLabel":{"type":["string","null"]},"draft":{"type":["object","null"],"additionalProperties":true,"description":"Staged edits not yet published (same fields as the live page). null = no draft."},"draftUpdatedAt":{"type":["string","null"],"format":"date-time"},"revision":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"PageSummary":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"isPublished":{"type":"boolean"},"hasDraft":{"type":"boolean"},"draftUpdatedAt":{"type":["string","null"],"format":"date-time"},"showInNav":{"type":"boolean"},"navOrder":{"type":"integer"},"navLabel":{"type":["string","null"]},"sectionCount":{"type":"integer"},"metadata":{"type":"object","properties":{"seoTitle":{"type":"string"},"seoDescription":{"type":"string"},"ogImage":{"type":"string"},"canonicalUrl":{"type":"string"},"noIndex":{"type":"boolean"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"PageUpdate":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"slug":{"type":"string","description":"Rename the page."},"showInNav":{"type":"boolean"},"navLabel":{"type":"string"},"navOrder":{"type":"integer"},"metadata":{"type":"object","properties":{"seoTitle":{"type":"string"},"seoDescription":{"type":"string"},"ogImage":{"type":"string"},"canonicalUrl":{"type":"string"},"noIndex":{"type":"boolean"}}},"navOverlay":{"type":["boolean","null"]},"navBackground":{"type":["string","null"],"enum":["auto","light","dark"]},"isPublished":{"type":"boolean","description":"true publishes the staged draft; false unpublishes."}}},"PageVersion":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"pageId":{"type":"string","format":"uuid"},"slug":{"type":"string"},"reason":{"type":"string","enum":["edit","publish","delete","restore"]},"createdAt":{"type":"string","format":"date-time"}}},"Settings":{"type":"object","properties":{"name":{"type":"string"},"curatorCode":{"type":["string","null"]},"description":{"type":["string","null"]},"bio":{"type":["string","null"]},"logoUrl":{"type":["string","null"]},"primaryColor":{"type":["string","null"]},"secondaryColor":{"type":["string","null"]},"accentColor":{"type":["string","null"]},"customDomain":{"type":["string","null"]},"subdomain":{"type":["string","null"]},"displayLayout":{"type":"string"},"facebookPixelId":{"type":["string","null"]},"customData":{"type":"object","additionalProperties":true}}},"SettingsUpdate":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":["string","null"],"maxLength":300},"bio":{"type":["string","null"],"maxLength":2000},"logoUrl":{"type":["string","null"]},"primaryColor":{"type":["string","null"],"description":"Any CSS color."},"secondaryColor":{"type":["string","null"],"description":"Any CSS color."},"accentColor":{"type":["string","null"],"description":"Any CSS color."},"displayLayout":{"type":"string","enum":["auto","cinema","vertical"]},"facebookPixelId":{"type":["string","null"],"description":"Numeric Meta Pixel ID.","pattern":"^\\d{5,20}$"},"customData":{"type":"object","additionalProperties":true,"description":"Merged into your existing custom data at the top level. Styles and scripts go through /content/styles; redirects through /content/redirects. Shapes for navigation, text styles, surface colors and newsletter keys are in GET /context `customization`."}}},"Styles":{"type":"object","properties":{"globalStyles":{"type":"string","description":"CSS applied to every page."},"headScripts":{"type":"string"},"footerScripts":{"type":"string"}}},"Redirect":{"type":"object","properties":{"from":{"type":"string","description":"Exact path on your site, e.g. /old-page. Must start with /; no query or host."},"to":{"type":"string","description":"Path on your site, e.g. /new-page (may include a ?query or #anchor)."},"permanent":{"type":"boolean","description":"Default true (308). false = temporary (307)."}},"required":["from","to"]},"EntityType":{"type":"string","enum":["screening","press_quote","press_outlet","podcast_episode","team_member"],"description":"New types are added by joma on request."},"Entity":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"entityType":{"$ref":"#/components/schemas/EntityType"},"data":{"type":"object","additionalProperties":true,"description":"Your data for this entity."},"sortOrder":{"type":"integer"},"isPublished":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Grant":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"filmSlug":{"type":"string"},"status":{"type":"string","enum":["pending","accepted","expired","revoked","declined"]},"expiresAt":{"type":["string","null"],"description":"null = permanent access.","format":"date-time"},"claimUrl":{"type":"string","description":"Link the recipient uses to claim access."},"grantedAt":{"type":["string","null"],"format":"date-time"}}},"GrantStatusFilter":{"type":"string","enum":["pending","accepted","revoked","declined"]},"FilmmakerCustomer":{"type":"object","properties":{"email":{"type":"string"},"firstPurchase":{"type":"string","format":"date-time"},"lastPurchase":{"type":"string","format":"date-time"},"totalPurchases":{"type":"integer"},"totalSpentCents":{"type":"integer","description":"Total charged, in cents."},"marketingOptOut":{"type":"boolean","description":"true = opted out of marketing. You must not include them in marketing campaigns."}}},"CuratorCustomer":{"allOf":[{"$ref":"#/components/schemas/FilmmakerCustomer"},{"type":"object","properties":{"filmsPurchased":{"type":"array","items":{"type":"string"},"description":"Titles bought through your curator link or code."},"yourEarningsCents":{"type":"integer","description":"Your earnings from this customer's purchases, in cents."}}}]},"CatalogFilm":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"shortDescription":{"type":["string","null"],"description":"Short hook / tagline-length blurb."},"longDescription":{"type":["string","null"],"description":"Synopsis."},"filmmakerBio":{"type":["string","null"],"description":"Per-film “About the filmmaker” text. null = your organization's bio is used."},"showFilmmakerBio":{"type":"boolean"},"posterUrl":{"type":["string","null"],"description":"Portrait poster."},"bannerUrl":{"type":["string","null"],"description":"Landscape 16:9 backdrop."},"trailerUrl":{"type":["string","null"]},"trailerKey":{"type":["string","null"]},"purchasePrice":{"type":["integer","null"],"description":"Purchase price in cents. Read-only via the API."},"rentalPrice":{"type":["integer","null"],"description":"Rental price in cents. Read-only via the API."},"rentalEnabled":{"type":"boolean"},"purchaseEnabled":{"type":"boolean"},"yearReleased":{"type":["integer","null"]},"durationMinutes":{"type":["integer","null"]},"genres":{"type":["array","null"],"items":{"type":"string"}},"director":{"type":["string","null"]},"cast":{"type":["array","null"],"items":{"type":"string"}},"producers":{"type":["array","null"],"items":{"type":"string"}},"kind":{"type":"string","enum":["internal","external"]},"status":{"type":"string","enum":["draft","available","unavailable"],"description":"Only `available` films can be bought or watched."},"marketplaceVisibility":{"type":"string","enum":["listed","unlisted","white_label_only"],"description":"Where the item is offered: listed on joma.film, unlisted (direct link only), or only on your own site. Set in the dashboard."},"standalonePurchase":{"type":"boolean","description":"false = sold only inside a bundle or season."},"seasonBundleId":{"type":["string","null"],"description":"The season this film is an episode of; null = not an episode.","format":"uuid"},"episodeNumber":{"type":["integer","null"]},"episodeAccess":{"type":["string","null"],"enum":["free","included","paid"],"description":"How the episode is reached, when the film is an episode."}},"required":["slug","title","status"]},"CatalogReview":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"quote":{"type":"string"},"attribution":{"type":["string","null"]},"linkUrl":{"type":["string","null"]},"displayOrder":{"type":"integer"},"featured":{"type":"boolean"}}},"FilmDetail":{"allOf":[{"$ref":"#/components/schemas/CatalogFilm"},{"type":"object","properties":{"reviews":{"type":"array","items":{"$ref":"#/components/schemas/CatalogReview"}},"editablePageKnobs":{"type":"array","items":{"type":"string"},"description":"displaySettings keys you may set on this film."}}}]},"DisplaySettings":{"type":"object","properties":{"pageLayout":{"type":["string","null"],"enum":["auto","hero","poster"]},"heroTheme":{"type":["string","null"],"enum":["auto","dark","light"]},"titleColor":{"type":["string","null"],"description":"Hex color, #rrggbb.","pattern":"^#[0-9a-fA-F]{6}$"},"presenterBadge":{"type":["string","null"],"maxLength":80},"supertitle":{"type":["string","null"],"maxLength":120},"hidePresentedBy":{"type":["boolean","null"]},"aboutLayout":{"type":["string","null"],"enum":["centered","image-text-quote"]},"aboutImageUrl":{"type":["string","null"],"description":"An https:// URL or a /path."}},"description":"How the film's page renders. Merged at the top level — send only the keys to change; `null` clears a key. pageLayout, heroTheme, titleColor are available on every film; presenterBadge, supertitle, hidePresentedBy, aboutLayout, aboutImageUrl only on films where joma has enabled them (see `editablePageKnobs` on GET). Any other key is rejected.","additionalProperties":false},"FilmUpdate":{"type":"object","properties":{"shortDescription":{"type":["string","null"]},"longDescription":{"type":["string","null"]},"filmmakerBio":{"type":["string","null"],"maxLength":2000},"featuredReviewIds":{"type":"array","items":{"type":"string"},"description":"Ids of this film's reviews to feature, in order. [] clears."},"displaySettings":{"$ref":"#/components/schemas/DisplaySettings"},"showTrailer":{"type":"boolean"},"showReviews":{"type":"boolean"},"showFilmmakerBio":{"type":"boolean"},"seasonBundleId":{"type":["string","null"],"description":"Season id (from the series endpoints). null detaches the episode.","format":"uuid"},"episodeNumber":{"type":["integer","null"],"minimum":1},"episodeAccess":{"type":["string","null"],"enum":["free","included","paid"],"description":"Making an episode `free` is a pricing change: set it in the dashboard. The API returns 403 for it."}},"additionalProperties":false,"description":"Send at least one field. Pricing, availability, visibility and video are managed in the dashboard; any other key returns 400."},"CatalogSeries":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"posterUrl":{"type":["string","null"]},"bannerUrl":{"type":["string","null"]},"trailerUrl":{"type":["string","null"]},"isVertical":{"type":"boolean","description":"Read-only."}}},"CatalogSeason":{"type":"object","properties":{"id":{"type":"string","description":"The season id (use as a film's seasonBundleId).","format":"uuid"},"seasonNumber":{"type":"integer"},"seasonTitle":{"type":["string","null"]},"name":{"type":"string"},"price":{"type":"integer","description":"Season price in cents. Read-only via the API."},"isActive":{"type":"boolean","description":"Whether the season is on sale. Set in the dashboard."},"marketplaceVisibility":{"type":"string","enum":["listed","unlisted","white_label_only"],"description":"Where the item is offered: listed on joma.film, unlisted (direct link only), or only on your own site. Set in the dashboard."}}},"CatalogEpisode":{"type":"object","properties":{"slug":{"type":"string","description":"The episode's film slug."},"title":{"type":"string"},"episodeNumber":{"type":["integer","null"]},"episodeAccess":{"type":["string","null"],"enum":["free","included","paid"]},"status":{"type":"string","enum":["draft","available","unavailable"]}}},"SeasonWithEpisodes":{"allOf":[{"$ref":"#/components/schemas/CatalogSeason"},{"type":"object","properties":{"episodes":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEpisode"}}}}]},"SeriesTree":{"allOf":[{"$ref":"#/components/schemas/CatalogSeries"},{"type":"object","properties":{"seasons":{"type":"array","items":{"$ref":"#/components/schemas/SeasonWithEpisodes"}}}}]},"SeriesInput":{"type":"object","properties":{"title":{"type":"string","maxLength":500},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens. Derived from the title if omitted.","pattern":"^[a-z0-9-]+$"},"description":{"type":["string","null"]},"posterUrl":{"type":["string","null"],"description":"http(s) URL.","maxLength":500},"bannerUrl":{"type":["string","null"],"description":"http(s) URL.","maxLength":500},"trailerUrl":{"type":["string","null"],"description":"http(s) URL.","maxLength":500}}},"MerchListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"price":{"type":"integer","description":"Amount in cents (integer)."},"imageUrl":{"type":["string","null"]},"options":{"type":["object","null"],"additionalProperties":true,"description":"Variants: { [option name]: string[] }."},"requiresShipping":{"type":"boolean"},"stockQuantity":{"type":["integer","null"],"description":"null = unlimited."},"isActive":{"type":"boolean"}}},"MerchItem":{"allOf":[{"$ref":"#/components/schemas/MerchListItem"},{"type":"object","properties":{"organizationId":{"type":"string","format":"uuid"},"fulfillmentProvider":{"type":"string"},"externalProductId":{"type":["string","null"]},"integrationId":{"type":["string","null"],"format":"uuid"},"variantMap":{"type":["object","null"],"additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}]},"MerchInput":{"type":"object","properties":{"name":{"type":"string","maxLength":255},"price":{"type":"integer","description":"Price in cents (integer ≥ 0)."},"description":{"type":["string","null"]},"imageUrl":{"type":["string","null"],"maxLength":500},"stockQuantity":{"type":["integer","null"],"description":"Integer ≥ 0; null = unlimited.","minimum":0},"isActive":{"type":"boolean","description":"Default true."},"options":{"type":["object","null"],"additionalProperties":true,"description":"Variants: { [option name]: string[] }, e.g. {\"Size\": [\"S\",\"M\",\"L\"]}."},"requiresShipping":{"type":"boolean"}}}},"responses":{"Error400":{"description":"Invalid request — the `error` message says which field and why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Error401":{"description":"Missing, invalid, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Error403":{"description":"Not allowed with an API key — do this in the joma dashboard.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Error404":{"description":"Not found — or not owned by your organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Error409":{"description":"Conflict with the current state (e.g. a duplicate slug, or a stale version).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Error413":{"description":"Request body too large.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Error429":{"description":"Rate limited. Back off and retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Error502":{"description":"An upstream step failed. Try again shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}