API
v1 Open mint

The mint API lets your own systems (for example a learning platform) read the catalogs, briefing templates and categories of your company in mint, create categories and order films: POST /films creates a film from a briefing (title, narration text, template or settings); mint can then plan it and produce it automatically up to the storyboard or the finished film. Read your films with GET /films and GET /films/{id} and cancel them with POST /films/{id}/cancel until the storyboard is ready. Follow changes in the event feed GET /events and download approved films with GET /films/{id}/file (and their subtitles). It is a server-to-server API: browsers on other sites cannot call it (no CORS).

Kurz auf Deutsch. Mit der mint API binden Sie mint an Ihre eigenen Systeme an, zum Beispiel an eine Lernplattform. Sie bestellen Filme aus einem Briefing, verfolgen den Fortschritt, geben Feedback zum Storyboard und laden freigegebene Filme herunter. Die Freigabe eines Films bleibt immer bei einer Person in mint. Die Referenz ist auf Englisch, wie die API selbst. Der schnellste Einstieg ist der Quickstart; Zugänge und Schlüssel legen Admins Ihrer Firma in mint unter Einstellungen → API-Zugänge an.

Base URL

https://api.cream-ai.de/api/v1. All paths in this document are relative to it. Requests and responses use JSON (UTF-8) unless an endpoint says otherwise, for example file downloads and uploads. All times are UTC in ISO 8601.

How a film flows through the API

  1. Read your catalogs once: templates, styles, brands, voices and categories.
  2. Order a film with POST /films. mint plans and produces it up to the storyboard (or the film).
  3. Follow its state with the event feed or GET /films/{id}/progress.
  4. Optionally review it: a storyboard preview, feedback on scenes, comments on the finished film.
  5. A person approves the film in mint. Then download it with GET /films/{id}/file.
Base URL
https://api.cream-ai.de/api/v1
Your first request
curl https://api.cream-ai.de/api/v1/me \
  -H "Authorization: Bearer $MINT_API_KEY"

From zero to a downloaded film in six steps. You need an API key with the scopes catalog:read, films:write, events:read and files:read.

1. Create an API key

A company admin creates an API access in mint under Settings → API access, chooses the scopes and copies the key. The key is shown only once. Keep it on your server, for example in an environment variable:

export MINT_API_KEY="mint_sk_live_…"

2. Check the key

GET /me shows the access, its company, scopes and limits. A 401 means the key is wrong, revoked or expired.

3. Pick a template

GET /templates lists the briefing templates of your company. A template fixes the style, brand, voice and further settings, so the order itself stays short. Use its key as template.

4. Order the film

POST /films with a title, the narration text, the e-mail address of the responsible mint user and your own video_key + version. With automation: "storyboard" (the default) mint plans and produces the storyboard and then waits for review. Sending the same order again returns the same film, so retries are safe.

5. Follow the progress

Poll the event feed, for example every few minutes, or read GET /films/{id}/progress while a person is watching. film.storyboard_ready tells you that the storyboard can be reviewed in mint; film.approved that the film is final.

6. Download the approved film

GET /films/{id}/file returns the MP4. Its ETag is the SHA-256 of the file; compare it after the download.

2. Check the key
curl https://api.cream-ai.de/api/v1/me \
  -H "Authorization: Bearer $MINT_API_KEY"
4. Order the film
curl -X POST https://api.cream-ai.de/api/v1/films \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Lesson 3: Market segmentation",
    "narration_text": "Not every customer wants the same thing. …",
    "user_email": "anna.schmidt@example.edu",
    "template": "lesson-standard",
    "video_key": "MKT101-lesson-03",
    "version": "1.0"
  }'
5. Follow the progress
curl "https://api.cream-ai.de/api/v1/events?after=0&types=film.storyboard_ready,film.approved" \
  -H "Authorization: Bearer $MINT_API_KEY"
6. Download the approved film
curl https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -o film.mp4 -D headers.txt
shasum -a 256 film.mp4   # compare with the ETag

Company admins create an API access in mint under Settings → API access. Each access has its own scopes and keys. A key is shown only once, right after it was created. Send it in the Authorization header:

curl -H "Authorization: Bearer mint_sk_live_…" https://api.cream-ai.de/api/v1/me

Keys in query strings are never accepted. GET /me shows the access, its company, scopes, key and limits. Revoking a key or changing scopes in mint takes effect immediately.

The mint API must be enabled for your company by mint. Until then, or after it was disabled, every request with a key of this company returns 403 api_not_enabled; your accesses and keys are kept and work again once the API is enabled.

Keep keys secret

  • Use the key only from your server. The API does not allow calls from browsers on other sites (no CORS).
  • Do not put keys into source code, URLs, tickets or logs. Store them in a secret store or an environment variable.
  • Each access can have up to two valid keys at the same time, so you can rotate a key without downtime: create the new key, deploy it, then revoke the old one.
  • An access can be limited to IP addresses and can expire. GET /me shows expires_at.
Authenticated request
curl https://api.cream-ai.de/api/v1/me \
  -H "Authorization: Bearer $MINT_API_KEY"
Missing or wrong key (401)
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key.",
    "request_id": "req_5b2e8f1a4c7d0e3b6a9f2c5d8e1b4a7c"
  }
}

Every API access has its own scopes. A request with a key that lacks a scope returns 403 forbidden_scope; details.required_scopes names what is missing. Writing scopes include reading the same area.

ScopeAllows
catalog:readRead approved styles, brands and voices and active briefing templates of this company as compact lists.
categories:readRead the category tree of this company, also by external key.
categories:writeCreate and rename categories and subcategories and link them to an external key. Includes categories:read.
films:readRead films, status and production progress.
films:writeCreate films from a briefing, have them produced automatically up to the storyboard or the film, and cancel them. Includes films:read.
files:readDownload approved film files and subtitles.
previews:readDownload the storyboard version of a film as MP4, also before approval.
previews:writeHave a storyboard preview of a film created as MP4. Each new preview costs credits. Includes previews:read.
events:readRead the continuous event feed of this company with a cursor (film objects in the feed only together with films:read).
uploads:writeUpload images and videos to use them in feedback and comments.
feedback:writeSend, cancel and retry feedback on scenes, and read and add comments on the finished film. Feedback changes the scenes like a message in the chat and may cost credits.
films:reviseHave open comments applied to the film; mint creates a new revision of the film from them (costs credits). Includes films:read.

GET /me and GET /openapi.json need no scope. More scopes follow with later versions.

Endpoints by scope

Missing scope (403)
{
  "error": {
    "code": "forbidden_scope",
    "message": "This API key does not have the scope films:write.",
    "request_id": "req_5b2e8f1a4c7d0e3b6a9f2c5d8e1b4a7c",
    "details": { "required_scopes": ["films:write"] }
  }
}

mint uses HTTP status codes: 2xx success, 4xx a problem with the request, 5xx a problem on the mint side.

All errors share one format:

{ "error": { "code": "forbidden_scope", "message": "…", "request_id": "req_…", "field": "…", "details": {} } }

code is stable and machine readable, message is for humans and may change, field names the affected input. Every response carries an X-Request-Id header; please quote it when you contact support.

Handling errors

  • Branch on error.code, never on message.
  • 429 and 503 are temporary: wait for Retry-After seconds and retry the same request with the same Idempotency-Key.
  • 409 codes with Retry-After (for example film_busy, idempotency_in_progress) are temporary as well.
  • New codes may be added within v1. Treat an unknown 4xx code like invalid_request and an unknown 5xx code like internal.

Error codes

CodeHTTP statusDescribed at
invalid_request400POST /films
invalid_json400general
invalid_cursor400GET /events
GET /films/{id}/comments
idempotency_key_required400POST /films
invalid_idempotency_key400general
parent_not_found400general
max_depth_exceeded400general
narration_too_long400general
user_not_in_company400general
template_not_found400general
category_not_found400general
feedback_kind_unsupported400general
upload_not_found400general
unauthorized401general
forbidden_scope403GET /operations/{id}
ip_not_allowed403GET /operations/{id}
insufficient_credits4025 endpoints
company_inactive403GET /operations/{id}
api_not_enabled403GET /operations/{id}
not_found40410 endpoints
not_approved404GET /films/{id}/file
GET /films/{id}/subtitles.srt
subtitles_not_available404GET /films/{id}/subtitles.srt
method_not_allowed–general
category_exists409POST /categories
external_key_exists409PATCH /categories/{id}
external_key_conflict409general
category_limit_reached409POST /categories
idempotency_in_progress4095 endpoints
version_conflict409POST /films
previous_version_creating409POST /films
film_deleted409POST /films
not_cancellable409POST /films/{id}/cancel
file_unavailable409GET /films/{id}/file
GET /films/{id}/storyboard-preview/file
GET /films/{id}/subtitles.srt
storyboard_not_ready409POST /films/{id}/feedback
POST /films/{id}/storyboard-preview
storyboard_not_current409POST /films/{id}/storyboard-preview
timeline_outdated409POST /films/{id}/feedback
preview_in_progress409POST /films/{id}/storyboard-preview
preview_not_ready409GET /films/{id}/storyboard-preview/file
preview_unsupported409POST /films/{id}/storyboard-preview
feedback_queue_full409POST /films/{id}/feedback
feedback_not_cancellable409POST /films/{id}/feedback/{feedback_id}/cancel
feedback_not_retryable409POST /films/{id}/feedback/{feedback_id}/retry
feedback_busy409POST /films/{id}/feedback/{feedback_id}/cancel
POST /films/{id}/feedback/{feedback_id}/retry
revision_locked409POST /films/{id}/comments
film_not_ready409GET /films/{id}/comments
POST /films/{id}/comments
POST /films/{id}/comments/apply
film_busy409POST /films/{id}/comments/apply
no_open_comments409POST /films/{id}/comments/apply
comments_not_open409POST /films/{id}/comments/apply
correction_in_progress409POST /films/{id}/comments/apply
upload_quota_exceeded409POST /uploads
film_cancelled4095 endpoints
cursor_expired410GET /events
preview_expired410GET /films/{id}/storyboard-preview/file
upload_expired410POST /films/{id}/comments
POST /films/{id}/feedback
GET /uploads/{id}
length_required411POST /uploads
payload_too_large413POST /uploads
unsupported_media_type415POST /uploads
file_content_mismatch415POST /uploads
range_not_satisfiable416GET /films/{id}/file
GET /films/{id}/storyboard-preview/file
GET /films/{id}/subtitles.srt
idempotency_mismatch422POST /films/{id}/comments/apply
POST /films/{id}/feedback
POST /films/{id}/storyboard-preview
scene_not_found422POST /films/{id}/feedback
rate_limited429GET /films/{id}/file
POST /uploads
internal500general
service_unavailable503PATCH /categories/{id}
Error response
{
  "error": {
    "code": "version_conflict",
    "message": "Version 1.0 of this video_key already exists with other content.",
    "request_id": "req_5b2e8f1a4c7d0e3b6a9f2c5d8e1b4a7c",
    "field": "version",
    "details": { "film_id": "k7m2xq9v4t8n1b5r3c6d0wza" }
  }
}
Response headers
HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_5b2e8f1a4c7d0e3b6a9f2c5d8e1b4a7c

Networks fail. With an Idempotency-Key you can safely send a writing request again: mint runs it at most once and returns the stored response for every repeat.

Writing POST requests require an Idempotency-Key header (1–128 visible ASCII characters, for example a UUID); PATCH accepts it optionally. POST /films accepts it optionally when the body has a video_key (the version identity then protects against duplicates); without video_key it is required (400 idempotency_key_required). POST /films/{id}/cancel accepts it optionally. Repeating a request with the same key and the same body returns the stored response with Idempotent-Replayed: true and changes nothing. This also applies to error responses (400, 404, 409): their body is replayed unchanged, so error.request_id names the original request, while X-Request-Id names the current one. Temporary rejections are not stored (409 feedback_busy, 409 film_busy, 409 preview_in_progress, 409 storyboard_not_ready, 402 insufficient_credits, 409 feedback_queue_full): a retry with the same key runs again once the reason is gone. The same key with a different request returns 422 idempotency_mismatch; while the first request is still running you get 409 idempotency_in_progress with Retry-After. Keys are kept per API access for 24 hours by default; the operator of a mint server can set 1–72 hours. GET /me shows the current value in idempotency_key_ttl_hours.

Good practice

  • Create a new random key (for example a UUID v4) for every new action, and reuse it only for retries of that action.
  • Store the key together with your own job, so a retry after a crash uses the same key.
  • For films, prefer video_key + version (see Film versions): they protect against duplicates for as long as the film exists, not only for 24 hours.
Request with Idempotency-Key
curl -X POST https://api.cream-ai.de/api/v1/categories \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: 9b1d3c5e-7f2a-4c6e-8a0b-2d4f6a8c0e1b" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Marketing", "external_key": "MKT" }'
Repeated request
HTTP/1.1 201 Created
Idempotent-Replayed: true
X-Request-Id: req_0c3e5a7b9d1f2e4a6c8b0d2f4e6a8c1b

Your system usually has its own id for a video, for example a lesson in a course. Send it as video_key, together with a version. mint then treats video_key + version as the identity of the film within your company.

  • Every film is ordered on behalf of a person: user_email must belong to an active member of your company. This person is the owner of the film in mint and gets the e-mail "storyboard ready", together with the admins of your company.
  • automation is storyboard (default), film or none. With automation, mint needs a fixed style (from the template or settings.style_id) and enough credits for the estimated film (402 insufficient_credits otherwise). The operator of a mint server can switch the automation off; films are then created without it and carry notice.code automation_disabled.
  • Credits are always taken from the credits of your company, never from a team budget. Each booking of an API film is marked "API" with the name of the access in the usage list of your company.
  • video_key + version identify a film version. The same order again returns the existing film (200, nothing is booked); a different order for an existing version returns 409 version_conflict.
  • Film status: briefing, in_production, storyboard_ready, film_ready, approved or cancelled. Only the approved original version is the film; format and language versions are not part of v1.

Versions in practice

You sendmint does
MKT101-lesson-03 1.0, first timecreates the film (201)
the same order againreturns the existing film (200), books nothing
1.0 again, but with a changed text409 version_conflict with details.film_id
1.1 with a changed textcreates a new film that takes over style, brand, voice and category of 1.0

Versions are major.minor or major.minor.patch without leading zeros. Use GET /films?video_key=… to list all versions of a video; is_latest_approved_version marks the newest approved one.

Order version 1.1
{
  "title": "Lesson 3: Market segmentation",
  "narration_text": "Not every customer wants the same thing. …",
  "user_email": "anna.schmidt@example.edu",
  "video_key": "MKT101-lesson-03",
  "version": "1.1"
}
All versions of a video
curl "https://api.cream-ai.de/api/v1/films?video_key=MKT101-lesson-03" \
  -H "Authorization: Bearer $MINT_API_KEY"

Lists return { "object": "list", "data": [], "has_more": false, "next_cursor": null }. Pass next_cursor as cursor to get the next page; limit is 1–100 (default 50). Cursors are opaque and only valid for the same query and filters.

The list object

objectstring
Always list
dataarray of anys
has_moreboolean
next_cursornullable string

Pass as cursor to get the next page; null on the last page.

The event feed is the exception: it pages with after and next_after instead of a cursor, see Event feed.

Read all pages (Node.js)
let cursor;
do {
  const url = new URL("https://api.cream-ai.de/api/v1/films");
  url.searchParams.set("limit", "100");
  if (cursor) url.searchParams.set("cursor", cursor);
  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.MINT_API_KEY}` },
  });
  const page = await res.json();
  for (const film of page.data) console.log(film.id, film.status);
  cursor = page.has_more ? page.next_cursor : null;
} while (cursor);
Read all pages (Python)
params = {"limit": 100}
while True:
    page = requests.get(f"{BASE}/films", headers=HEADERS, params=params).json()
    for film in page["data"]:
        print(film["id"], film["status"])
    if not page["has_more"]:
        break
    params["cursor"] = page["next_cursor"]

mint v1 has no webhooks. Instead, every company has an ordered event feed: you ask for everything after the last event you processed. This works behind firewalls, needs no public endpoint on your side and never loses an event while your system is down.

A person approves a film in mint; only then can it be downloaded. The key needs films:read, events:read and files:read. Downloads and the feed are free of credits.

  1. GET /events?limit=1: note latest_seq as H.
  2. GET /films?status=approved (all pages): download each film from file_url and compare the SHA-256 of the bytes with the ETag.
  3. From then on, for example once a day: GET /events?after=H&types=film.approved,film.approval_revoked,film.deleted, process the events, store next_after as the new H, repeat while has_more.
  4. 410 cursor_expired or 400 invalid_cursor: start again with step 1.

A film can be downloaded as long as its approval is active: after a revocation the download returns 404 not_approved; after a new approval only the new revision is available. Films that change between step 1 and 2 come twice; that is harmless because the SHA-256 identifies the file.

Event types

  • film.created
  • film.status_changed
  • film.storyboard_ready
  • film.approved
  • film.approval_revoked
  • film.cancelled
  • film.deleted
  • film.progress
  • feedback.updated
  • storyboard.preview_ready
  • operation.completed

New types may be added within v1; ignore types you do not know. Events are kept for 180 days.

Rules for a robust consumer

  • Store next_after only after the page was processed. If you crash in between, you read the page again.
  • Events can come twice (at least once delivery). Use the event id to skip duplicates.
  • data is a snapshot at the time of the event; film (with films:read) is the current state.
  • Poll every few minutes. There is no need to poll faster than once a minute.
Poll the feed (Node.js)
let after = await loadCursor(); // e.g. from your database, start with "0"
for (;;) {
  const url = new URL("https://api.cream-ai.de/api/v1/events");
  url.searchParams.set("after", after);
  url.searchParams.set("types", "film.approved,film.approval_revoked,film.deleted");
  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.MINT_API_KEY}` },
  });
  if (res.status === 410 || res.status === 400) {
    after = await resync(); // step 1 and 2 above
    continue;
  }
  const page = await res.json();
  for (const event of page.data) await handle(event);
  after = String(page.next_after);
  await saveCursor(after);
  if (!page.has_more) break;
}

Approved films are downloaded with GET /films/{id}/file, their subtitles with GET /films/{id}/subtitles.srt. Storyboard previews work the same way with GET /films/{id}/storyboard-preview/file. Downloads are free of credits.

ETag = SHA-256

Every file comes with a strong ETag: the SHA-256 of the file in quotes. For films it equals approval.sha256 of the film. Compute the SHA-256 of the bytes you received and compare. If an event is older than the current approval, the ETag counts.

Resume a download

Send Range: bytes=<from>- together with If-Range: <ETag>. If the file is unchanged, mint answers 206 with the rest; if a new approval exists in the meantime, 200 with the whole new file. One range per request is supported.

Skip unchanged files

Send If-None-Match: <ETag>. mint answers 304 without a body if you already have the current file. HEAD returns the headers only.

When a download is not possible

ResponseMeaning
404 not_approvedThe film has no active approval (never approved, or revoked).
404 subtitles_not_availableThe approval has no subtitles.
409 file_unavailableThe file is temporarily not available. Retry later.
429 rate_limitedToo many downloads at the same time (details.reason parallel_downloads). Wait for Retry-After.
503mint is briefly checking the file. Wait for Retry-After.
Download and verify
curl https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -D headers.txt -o film.mp4
grep -i etag headers.txt
shasum -a 256 film.mp4
Resume an interrupted download
curl https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Range: bytes=33554432-" \
  -H 'If-Range: "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"' \
  -o film.part

Long-running requests answer 202 Accepted with a Location header that points to /api/v1/operations/{id} and an Operation object. Poll it until status is succeeded or failed. Operation types are storyboard.preview and film.comments_apply; more may follow within v1.

The operation also reports its end in the event feed (operation.completed), so you can follow it there instead of polling. See Operations for the object and the endpoint.

Start
HTTP/1.1 202 Accepted
Location: /api/v1/operations/op_4d9b2e7a1c6f3d8b5e0a2c7f9b4d1e6a
Poll
curl https://api.cream-ai.de/api/v1/operations/op_4d9b2e7a1c6f3d8b5e0a2c7f9b4d1e6a \
  -H "Authorization: Bearer $MINT_API_KEY"

Requests are limited per key and per company; GET /me shows the limits in rate_limits. Exceeding a limit returns 429 rate_limited with Retry-After (seconds). JSON request bodies may be at most 256 KB and nested at most 32 levels deep (otherwise 400 invalid_request with field body). An error before the body was read closes the connection (Connection: close). Catalog lists (styles, brands, voices) and the category list may show changes with a delay of up to 30 seconds.

Fixed limits

WhatLimit
JSON request body256 KB, nested at most 32 levels
narration_text18,000 characters
Page size (limit)1–100, default 50
Uploadsimages up to 25 MB, videos up to 200 MB, kept 7 days after the last use
Idempotency keyskept 24 hours by default (GET /me shows the current value)
Eventskept 180 days
Too many requests
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Retry after 12 seconds.",
    "request_id": "req_5b2e8f1a4c7d0e3b6a9f2c5d8e1b4a7c"
  }
}

Within v1 there are only additions: new endpoints, new optional request fields, new response fields and new enum values. Ignore fields you do not know. Breaking changes come with a new version (/api/v2).

The version is part of the path (/api/v1). GET /me shows it in api_version. The complete contract is available as OpenAPI 3.1 at GET /openapi.json, for example to generate a client.

OpenAPI contract
curl https://api.cream-ai.de/api/v1/openapi.json -o mint-api-v1.openapi.json

An API access (service account) belongs to one company. It has scopes, up to two keys and optional limits such as an expiry date or allowed IP addresses. Company admins manage accesses in mint under Settings → API access.

Attributes

objectstring
Always api_client
idstring (uuid)
namestring
organizationobject
Show child attributes
idstring

Company id in mint.

namestring
scopesarray of strings

Scopes granted to this access (without implied scopes).

expires_atnullable string (date-time)

Expiry of this API access, set by a company admin in mint. Afterwards every key of the access is rejected with 401. null if the access does not expire.

keyobject
Show child attributes
idstring (uuid)
prefixstring

Visible part of the key.

expires_atnullable string (date-time)

End of the grace period of this key after a rotation; null if the key itself has no end. The access can still expire earlier, see expires_at of the access.

rate_limitsobject
Show child attributes
read_per_minuteinteger

Read requests per minute for this key.

Minimum 1
write_per_minuteinteger

Write requests per minute for this key.

Minimum 1
organization_read_per_minuteinteger

Read requests per minute for all keys of the company.

Minimum 1
organization_write_per_minuteinteger

Write requests per minute for all keys of the company.

Minimum 1
idempotency_key_ttl_hoursinteger

How long an Idempotency-Key of this access is kept, in hours (default 24).

Minimum 1
api_versionstring
Always v1
The API access object
{
  "object": "api_client",
  "id": "0f6c2a9e-4b7d-4e1a-8c3f-5d2b9e7a1c64",
  "name": "Learning platform",
  "organization": {
    "id": "org_4821",
    "name": "Northwind University"
  },
  "scopes": [
    "catalog:read",
    "categories:write",
    "films:write",
    "files:read",
    "events:read"
  ],
  "expires_at": null,
  "key": {
    "id": "8e3b1d7a-2c5f-4a9e-b6d0-1f4c8a2e7b53",
    "prefix": "mint_sk_live_3fa9c2e71b",
    "expires_at": null
  },
  "rate_limits": {
    "read_per_minute": 300,
    "write_per_minute": 60,
    "organization_read_per_minute": 1200,
    "organization_write_per_minute": 240
  },
  "idempotency_key_ttl_hours": 24,
  "api_version": "v1"
}

Returns the API access (service account) the key belongs to, its company, scopes, key and limits. Needs a valid key, but no scope.

ScopeA valid API key, no scope.

Returns

200

The API access of this key. Returns the API access object.

Errors 401 · 403 · 429 · 500 · 503
401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/me
curl "https://api.cream-ai.de/api/v1/me" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "api_client",
  "id": "0f6c2a9e-4b7d-4e1a-8c3f-5d2b9e7a1c64",
  "name": "Learning platform",
  "organization": {
    "id": "org_4821",
    "name": "Northwind University"
  },
  "scopes": [
    "catalog:read",
    "categories:write",
    "films:write",
    "files:read",
    "events:read"
  ],
  "expires_at": null,
  "key": {
    "id": "8e3b1d7a-2c5f-4a9e-b6d0-1f4c8a2e7b53",
    "prefix": "mint_sk_live_3fa9c2e71b",
    "expires_at": null
  },
  "rate_limits": {
    "read_per_minute": 300,
    "write_per_minute": 60,
    "organization_read_per_minute": 1200,
    "organization_write_per_minute": 240
  },
  "idempotency_key_ttl_hours": 24,
  "api_version": "v1"
}

This API description (OpenAPI 3.1)

GET/api/v1/openapi.json
View as Markdown

Returns this document. Needs no key; responses may be cached for 5 minutes.

ScopeNo API key needed.

Returns

200

The OpenAPI document of the mint API v1.

Errors 429 · 500 · 503
429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/openapi.json
curl "https://api.cream-ai.de/api/v1/openapi.json"
Response 200
{
  "openapi": "3.1.0",
  "info": {
    "title": "mint API",
    "version": "1.0.0",
    "description": "…"
  },
  "paths": {
    "…": {}
  }
}

A film is ordered from a briefing: a title, the narration text and the mint user who is responsible for it. mint plans and produces it automatically up to the storyboard (automation: "storyboard") or up to the film ("film"). People review and approve the film in mint; the API never approves a film.

Status. briefing → in_production → storyboard_ready → film_ready → approved, or cancelled. stage shows the detailed stage as in the mint project list, attention_required and notice tell you when a person needs to act in mint.

Only films ordered through the API are visible to the API. Credits are always taken from your company.

A film ordered through the API. source is currently always api; app is reserved for projects created in mint, which v1 does not return yet.

Attributes

objectstring
Always film
idstring

Id of the film in mint.

titlestring

Title as it is in mint now (people can change it there).

statusenum

briefing: created in mint, nothing is running (for example with automation: none). in_production: mint is planning or producing the storyboard (or the film). storyboard_ready: the storyboard is ready for review in mint. With automation: storyboard the film stops here until a person continues in mint. film_ready: the film is rendered and waits for approval by a person in mint. approved: a person approved the film in mint. cancelled: the film was cancelled. New values may be added within v1.

stagenullable enum

Detailed stage as shown in the mint project list, or null if unknown. New values may be added within v1.

Possible values briefing style voice ready_to_plan planning storyboard_in_progress storyboard_review film_rendering film_ready approved paused error cancelled
attention_requiredboolean

true if a person needs to act in mint (see notice).

noticenullable object

Why a person needs to act in mint, or null. Codes: production_paused (“Production is paused in mint. Someone needs to resume it.”), production_failed (“Production failed in mint. Someone needs to check it.”), planning_failed (“Planning the storyboard failed in mint. Someone needs to check it.”), automation_failed (“The automatic storyboard could not be completed. Someone needs to continue in mint.”), insufficient_credits (“The company does not have enough credits. Someone needs to add credits and continue in mint.”), automation_disabled (“Automatic production is currently switched off. Someone needs to continue in mint.”).

Show child attributes
codeenum
Possible values production_paused production_failed planning_failed automation_failed insufficient_credits automation_disabled
messagestring

Short English text (may change).

sourceenum

api: ordered through the API; app: reserved for projects created in mint (not returned in v1).

automationnullable enum

none: mint only creates the film with its briefing; people continue in mint. storyboard (default): mint plans and produces the storyboard automatically and stops at storyboard_ready for review. film: mint also renders the film without stopping at the storyboard (status film_ready). The film is always approved by a person in mint, never by the API.

video_keynullable string

Your key of the video, as sent.

versionnullable string

Version of the video, canonical (1.0.0 is returned as 1.0).

previous_version_idnullable string

Id of the film with the next lower version of the same video_key, or null.

is_latest_approved_versionboolean

true only if this film is approved and no higher, approved and not cancelled version of the same video_key exists.

languagenullable enum

Language of the film.

Possible values de en fr es it pt nl pl cs sk hu ro hr sl sv da no fi tr id vi el uk ru bg
templatenullable string

Key of the template used when the film was created.

settingsobject

Effective settings of the film in mint. Values that are not set (or that mint cannot express in the API) are null.

Show child attributes
formatnullable enum

Aspect ratio.

Possible values 16x9 9x16 1x1
style_idnullable string

Id of the style (see GET /styles).

style_revisionnullable integer

Revision of the style the film uses.

Minimum 1
brand_idnullable string

Effective brand (see GET /brands); null = no brand.

voice_idnullable string

Voice of the narration (may also be a voice from the mint voice library); null = none set yet.

voice_namenullable string

Name of the voice.

narration_modenullable enum

verbatim (default): narration_text is spoken word for word. smooth: mint polishes the language of narration_text and keeps its content. free: narration_text is the briefing; mint writes the narration freely (use target_duration_s for the length).

temponullable enum

Pace of the film.

Possible values presenting lively kinetic
freedomnullable enum

Creative freedom in percent.

Possible values 0 25 40 65 100
video_sharenullable enum

Share of moving video clips in percent.

Possible values 0 25 50 75 100
target_duration_snullable integer

Target duration in seconds (in steps of 6 seconds).

Minimum 1
categorynullable object

Category of the film in mint (see GET /categories), or null.

Show child attributes
objectstring
Always category
idstring

Id of the category.

namestring
external_keynullable string

Key of the connected system, if set.

parentnullable object

Top-level category of a subcategory; null for a top-level category.

Show child attributes
idstring
namestring
external_keynullable string
requested_bynullable objectPersonal data

The mint user from user_email of the request (a Person with kind user). This user is responsible for the film in mint and is notified when the storyboard is ready. Personal data.

Show child attributes
kindenum

Always user.

Possible values user
emailstringPersonal data

E-mail address (lower case).

namenullable stringPersonal data

Name of the user at the time the film was created.

metadataobject

Your metadata, as sent. mint never uses it for the film. Key order is kept in POST /films (first response), GET /films and GET /films/{id}; a replayed response may order keys differently.

approvalnullable object

The active approval of the film (only the approved original version is the film), or null.

Show child attributes
revisioninteger

Approved revision of the film.

Minimum 1
approved_atstring (date-time)

Time of the approval (UTC).

sha256nullable string

SHA-256 of the approved file (hex).

bytesnullable integer

Size of the approved file in bytes.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

mimenullable string

Media type of the file, e.g. video/mp4.

has_subtitlesboolean

true if subtitles were frozen with this approval (subtitles_url).

approved_bynullable objectPersonal data

Who approved the film in mint (kind user, name and e-mail; email is null for approvals before 9 November 2026). Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

cancelled_atnullable string (date-time)

Time of the cancellation (UTC), or null.

created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

app_urlnullable string

Link to the film in mint (for people with access), or null.

file_urlnullable string

Path of the approved file (GET /films/{id}/file, relative to the host of the API), or null without an active approval.

subtitles_urlnullable string

Path of the subtitles of the approval (GET /films/{id}/subtitles.srt), or null if the approval has none.

revisionsarray of objects

Rendered revisions of the film, newest last (only in GET /films/{id}, without file links).

Show child attributes
revisioninteger

Number of the rendered revision.

Minimum 1
statusenum

rendering, ready or failed.

created_atnullable string (date-time)

Start of the render (UTC).

finished_atnullable string (date-time)

End of the render (UTC), null while rendering.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

The film object
{
  "object": "film",
  "id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "title": "Lesson 3: Market segmentation",
  "status": "approved",
  "stage": "approved",
  "attention_required": false,
  "notice": null,
  "source": "api",
  "automation": "storyboard",
  "video_key": "MKT101-lesson-03",
  "version": "1.0",
  "previous_version_id": null,
  "is_latest_approved_version": true,
  "language": "de",
  "template": "lesson-standard",
  "settings": {
    "format": "16x9",
    "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
    "style_revision": 4,
    "brand_id": "brand-northwind-x7k2p9",
    "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
    "voice_name": "Clara",
    "narration_mode": "verbatim",
    "tempo": "presenting",
    "freedom": 40,
    "video_share": 25,
    "target_duration_s": 180
  },
  "category": {
    "object": "category",
    "id": "rz3p8w1d6c0b",
    "name": "MKT101 Marketing basics",
    "external_key": "MKT101",
    "parent": {
      "id": "mk7t2q9x4v1n",
      "name": "Marketing",
      "external_key": "MKT"
    }
  },
  "requested_by": {
    "kind": "user",
    "email": "anna.schmidt@example.edu",
    "name": "Anna Schmidt"
  },
  "metadata": {
    "course_id": "MKT101",
    "lesson": 3
  },
  "approval": {
    "revision": 2,
    "approved_at": "2026-11-11T14:30:00Z",
    "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
    "bytes": 48213377,
    "duration_s": 184.6,
    "resolution": "1920x1080",
    "mime": "video/mp4",
    "has_subtitles": true,
    "approved_by": {
      "kind": "user",
      "name": "Anna Schmidt",
      "email": "anna.schmidt@example.edu"
    }
  },
  "cancelled_at": null,
  "created_at": "2026-11-10T08:00:00Z",
  "updated_at": "2026-11-11T14:30:00Z",
  "app_url": "https://app.cream-ai.de/editorial/k7m2xq9v4t8n1b5r3c6d0wza",
  "file_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file",
  "subtitles_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/subtitles.srt",
  "revisions": [
    {
      "revision": 1,
      "status": "ready",
      "created_at": "2026-11-10T08:21:37Z",
      "finished_at": "2026-11-10T08:39:10Z",
      "duration_s": 181.2,
      "resolution": "1920x1080"
    },
    {
      "revision": 2,
      "status": "ready",
      "created_at": "2026-11-11T13:50:00Z",
      "finished_at": "2026-11-11T14:05:41Z",
      "duration_s": 184.6,
      "resolution": "1920x1080"
    }
  ]
}

Creates a film from a briefing in mint and, depending on automation, starts the automatic production. The film is always created with the settings of its template (template), the previous version and settings (in this order, settings wins).

Same order, same film. With video_key, the company-wide identity of a film is video_key + version. Sending the same order again (same title, narration_text, user_email, language, template, settings, category and automation) returns 200 with the existing film, even after the Idempotency-Key expired and with any key; nothing is created or charged again. metadata is not part of this comparison and is never changed by a repeated order. The same video_key and version with other content returns 409 version_conflict with details.film_id. While the same version is still being created you get 409 idempotency_in_progress with Retry-After; while a lower version of the same video_key is still being created, 409 previous_version_creating with Retry-After. A cancelled or deleted film frees its version: the same order then creates a new film. A setting that cannot be applied returns 400 invalid_request with field and details.code (style_not_available, style_not_approved, brand_not_available, voice_not_available, invalid_value, unsupported_version, unknown_setting, ai_music_not_enabled or not_applicable) and details.setting.

Idempotency-Key. Optional with video_key; without video_key it is required (400 idempotency_key_required). Errors that happen before mint reserved the order (for example 400 for a template that is not active) are not stored under the key, so you can correct the request and retry with the same key. A film without video_key that was deleted in mint returns 409 film_deleted for its key.

Automation. With automation other than none, a style must be set (by the template, the previous version or settings.style_id), otherwise 400 invalid_request (field settings.style_id). mint estimates the credits from the text length and the automation level; if the company does not have enough credits, the response is 402 insufficient_credits and nothing is created. Credits are always charged to the company, never to a team budget. If the automatic production cannot start, the film is still created (201) and notice tells what to do in mint. The request body may be at most 256 KB.

Headers

Idempotency-Keystring

Optional unique key of this write request (1–128 visible ASCII characters). Retries with the same key return the stored response.

1–128 characters

Request body

titlestringRequired

Title of the film (trimmed).

1–200 characters
narration_textstringRequired

Text of the film (trimmed, 1–18,000 characters; longer texts return 400 narration_too_long). How it is used depends on settings.narration_mode. Tabs and line breaks are allowed, other control characters are not.

1–18,000 characters
user_emailstring (email)Required

E-mail address of an active mint user of this company. The user becomes responsible for the film in mint and gets the e-mail when the storyboard is ready. Otherwise 400 user_not_in_company (field user_email). Compared without case.

Up to 254 characters
languageenum

Language of the film. Without it, the template, then the previous version, then de applies.

Possible values de en fr es it pt nl pl cs sk hu ro hr sl sv da no fi tr id vi el uk ru bg
templatestring

Key of an active briefing template (GET /templates). Unknown or inactive keys return 400 template_not_found.

automationenum

none: mint only creates the film with its briefing; people continue in mint. storyboard (default): mint plans and produces the storyboard automatically and stops at storyboard_ready for review. film: mint also renders the film without stopping at the storyboard (status film_ready). The film is always approved by a person in mint, never by the API.

Default storyboard
settingsobject

Optional settings. They win over the template and the previous version; unknown keys return 400 invalid_request with field settings.<name>. The template may set further mint settings (for example music, depth or audience) that are not listed here.

Show child attributes
formatenum

Aspect ratio (16x9, 9x16, 1x1; 16:9 etc. are accepted, too).

style_idstring

Id of an approved style of the company (GET /styles).

1–120 characters
brand_idnullable string

Id of a brand (GET /brands), or null for no brand. Omit it to keep the brand of the template, the previous version or mint’s automatic choice.

1–120 characters
voice_idnullable string

Voice id from GET /voices, or null for the automatic voice (the voice of the brand, if it has one).

narration_modeenum

verbatim (default): narration_text is spoken word for word. smooth: mint polishes the language of narration_text and keeps its content. free: narration_text is the briefing; mint writes the narration freely (use target_duration_s for the length).

Default verbatim
tempoenum

Pace of the film.

Possible values presenting lively kinetic
freedomenum

Creative freedom in percent.

Possible values 0 25 40 65 100
video_shareenum

Share of moving video clips in percent.

Possible values 0 25 50 75 100
target_duration_sinteger

Target duration in seconds (1–900). mint keeps the length in steps of 6 seconds (0.1 minutes), so the value is rounded to the nearest 6 seconds (at least 6 seconds) and returned that way.

1–900
categoryobject

Category of the film. Allowed forms: { "id" }, { "external_key" }, { "path", "create"? } or { "path", "external_key", "create"? }. With path and external_key, mint first looks for the key; if it is missing and create is true, the path is created and the key is set on its last level. Path and key pointing to different categories return 400 invalid_request (field category). A category that does not exist returns 400 category_not_found. create: true also needs the scope categories:write (otherwise 403 forbidden_scope).

Show child attributes
idstring

Id of a category (GET /categories). Not combinable with other fields.

external_keystring

External key of a category (e.g. a module number).

1–100 characters
patharray of strings

Category names: [main] or [main, sub] (compared without case).

Up to 2 items
createboolean

Create missing levels of path.

Default false
video_keystring

Your stable key of the video (case-sensitive). Together with version it identifies the film within the company.

Up to 200 characters
versionstring

Version of the video (major.minor or major.minor.patch, numbers without leading zeros). A higher version of the same video_key takes over style, brand, voice and category of the next lower version, unless set in the request.

Default 1.0
metadataobject

Your own data (JSON object, at most 16,384 bytes as UTF-8 JSON, nested at most 8 levels). mint stores and returns it unchanged and never uses it for the film. It is not part of the order identity.

Returns

200

The same order already exists (same video_key, version and content); the existing film is returned and nothing was created. Returns the film object.

201

The film was created. Returns the film object.

Location Path of the film: /api/v1/films/{id}.
Errors 400 · 401 · 402 · 403 · 404 · 409 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

402

The company does not have enough credits for the requested automation (insufficient_credits). Nothing was created; add credits in mint and retry.

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

Conflict (category_exists, external_key_exists, external_key_conflict, category_limit_reached, idempotency_in_progress, version_conflict, previous_version_creating, film_deleted, not_cancellable, file_unavailable, storyboard_not_ready, storyboard_not_current, timeline_outdated, preview_in_progress, preview_not_ready, preview_unsupported, feedback_queue_full, feedback_not_cancellable, feedback_not_retryable, feedback_busy, revision_locked, film_not_ready, film_busy, no_open_comments, comments_not_open, correction_in_progress, upload_quota_exceeded, film_cancelled).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/films
curl -X POST "https://api.cream-ai.de/api/v1/films" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Lesson 3: Market segmentation",
    "narration_text": "Not every customer wants the same thing. In this lesson we look at how companies divide a market into groups …",
    "user_email": "anna.schmidt@example.edu",
    "language": "de",
    "template": "lesson-standard",
    "automation": "storyboard",
    "category": {
      "external_key": "MKT101"
    },
    "video_key": "MKT101-lesson-03",
    "version": "1.0",
    "metadata": {
      "course_id": "MKT101",
      "lesson": 3
    }
  }'
Response 201
{
  "object": "film",
  "id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "title": "Lesson 3: Market segmentation",
  "status": "in_production",
  "stage": "planning",
  "attention_required": false,
  "notice": null,
  "source": "api",
  "automation": "storyboard",
  "video_key": "MKT101-lesson-03",
  "version": "1.0",
  "previous_version_id": null,
  "is_latest_approved_version": true,
  "language": "de",
  "template": "lesson-standard",
  "settings": {
    "format": "16x9",
    "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
    "style_revision": 4,
    "brand_id": "brand-northwind-x7k2p9",
    "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
    "voice_name": "Clara",
    "narration_mode": "verbatim",
    "tempo": "presenting",
    "freedom": 40,
    "video_share": 25,
    "target_duration_s": 180
  },
  "category": {
    "object": "category",
    "id": "rz3p8w1d6c0b",
    "name": "MKT101 Marketing basics",
    "external_key": "MKT101",
    "parent": {
      "id": "mk7t2q9x4v1n",
      "name": "Marketing",
      "external_key": "MKT"
    }
  },
  "requested_by": {
    "kind": "user",
    "email": "anna.schmidt@example.edu",
    "name": "Anna Schmidt"
  },
  "metadata": {
    "course_id": "MKT101",
    "lesson": 3
  },
  "approval": null,
  "cancelled_at": null,
  "created_at": "2026-11-10T08:00:00Z",
  "updated_at": "2026-11-10T08:00:04Z",
  "app_url": "https://app.cream-ai.de/editorial/k7m2xq9v4t8n1b5r3c6d0wza",
  "file_url": null,
  "subtitles_url": null,
  "revisions": [],
  "latest_revision": null
}

Get a film

GET/api/v1/films/{id}
View as Markdown

The current state of a film ordered through the API, with its rendered revisions. Unknown ids, projects created in mint, films of other companies and films deleted in mint return 404 not_found.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Returns

200

The film. Returns the film object.

Errors 401 · 403 · 404 · 429 · 500 · 503
401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "film",
  "id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "title": "Lesson 3: Market segmentation",
  "status": "approved",
  "stage": "approved",
  "attention_required": false,
  "notice": null,
  "source": "api",
  "automation": "storyboard",
  "video_key": "MKT101-lesson-03",
  "version": "1.0",
  "previous_version_id": null,
  "is_latest_approved_version": true,
  "language": "de",
  "template": "lesson-standard",
  "settings": {
    "format": "16x9",
    "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
    "style_revision": 4,
    "brand_id": "brand-northwind-x7k2p9",
    "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
    "voice_name": "Clara",
    "narration_mode": "verbatim",
    "tempo": "presenting",
    "freedom": 40,
    "video_share": 25,
    "target_duration_s": 180
  },
  "category": {
    "object": "category",
    "id": "rz3p8w1d6c0b",
    "name": "MKT101 Marketing basics",
    "external_key": "MKT101",
    "parent": {
      "id": "mk7t2q9x4v1n",
      "name": "Marketing",
      "external_key": "MKT"
    }
  },
  "requested_by": {
    "kind": "user",
    "email": "anna.schmidt@example.edu",
    "name": "Anna Schmidt"
  },
  "metadata": {
    "course_id": "MKT101",
    "lesson": 3
  },
  "approval": {
    "revision": 2,
    "approved_at": "2026-11-11T14:30:00Z",
    "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
    "bytes": 48213377,
    "duration_s": 184.6,
    "resolution": "1920x1080",
    "mime": "video/mp4",
    "has_subtitles": true,
    "approved_by": {
      "kind": "user",
      "name": "Anna Schmidt",
      "email": "anna.schmidt@example.edu"
    }
  },
  "cancelled_at": null,
  "created_at": "2026-11-10T08:00:00Z",
  "updated_at": "2026-11-11T14:30:00Z",
  "app_url": "https://app.cream-ai.de/editorial/k7m2xq9v4t8n1b5r3c6d0wza",
  "file_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file",
  "subtitles_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/subtitles.srt",
  "revisions": [
    {
      "revision": 1,
      "status": "ready",
      "created_at": "2026-11-10T08:21:37Z",
      "finished_at": "2026-11-10T08:39:10Z",
      "duration_s": 181.2,
      "resolution": "1920x1080"
    },
    {
      "revision": 2,
      "status": "ready",
      "created_at": "2026-11-11T13:50:00Z",
      "finished_at": "2026-11-11T14:05:41Z",
      "duration_s": 184.6,
      "resolution": "1920x1080"
    }
  ]
}

List films

GET/api/v1/films
View as Markdown

Films of the company, sorted by created_at (oldest first), then id; new films usually appear at the end. Lists the films of the company that were ordered through the API; every active API access of the company can read them. Projects created in mint are not listed (other sources may be added later). Each film appears at most once while paging. A film created in the same second as a page is read can, rarely, be sorted before the cursor. With status mint filters while reading: a page can be shorter than limit (even empty) and still have has_more: true; keep paging with next_cursor. limit is 1–100. Title and category in the list can be up to 10 minutes behind mint; GET /films/{id} shows the current state. A film deleted in mint disappears from the list.

Query parameters

limitinteger

Page size (1–100).

Default 50 · 1–100
cursorstring

Opaque cursor from next_cursor of the previous page.

Up to 2,048 characters
statusenum

Only films with this status.

Possible values briefing in_production storyboard_ready film_ready approved cancelled
video_keystring

Only films with this video_key (all versions, exact match, case-sensitive).

Up to 200 characters
category_idstring

Only films in this category; for a top-level category also in its subcategories.

sourceenum

api: films ordered through the API (default and currently the only value; other sources may be added later).

Default api
Possible values api

Returns

200

One page of films.

Show response attributes
objectstring
Always list
dataarray of film objects
Show child attributes
objectstring
Always film
idstring

Id of the film in mint.

titlestring

Title as it is in mint now (people can change it there).

statusenum

briefing: created in mint, nothing is running (for example with automation: none). in_production: mint is planning or producing the storyboard (or the film). storyboard_ready: the storyboard is ready for review in mint. With automation: storyboard the film stops here until a person continues in mint. film_ready: the film is rendered and waits for approval by a person in mint. approved: a person approved the film in mint. cancelled: the film was cancelled. New values may be added within v1.

stagenullable enum

Detailed stage as shown in the mint project list, or null if unknown. New values may be added within v1.

Possible values briefing style voice ready_to_plan planning storyboard_in_progress storyboard_review film_rendering film_ready approved paused error cancelled
attention_requiredboolean

true if a person needs to act in mint (see notice).

noticenullable object

Why a person needs to act in mint, or null. Codes: production_paused (“Production is paused in mint. Someone needs to resume it.”), production_failed (“Production failed in mint. Someone needs to check it.”), planning_failed (“Planning the storyboard failed in mint. Someone needs to check it.”), automation_failed (“The automatic storyboard could not be completed. Someone needs to continue in mint.”), insufficient_credits (“The company does not have enough credits. Someone needs to add credits and continue in mint.”), automation_disabled (“Automatic production is currently switched off. Someone needs to continue in mint.”).

Show child attributes
codeenum
Possible values production_paused production_failed planning_failed automation_failed insufficient_credits automation_disabled
messagestring

Short English text (may change).

sourceenum

api: ordered through the API; app: reserved for projects created in mint (not returned in v1).

automationnullable enum

none: mint only creates the film with its briefing; people continue in mint. storyboard (default): mint plans and produces the storyboard automatically and stops at storyboard_ready for review. film: mint also renders the film without stopping at the storyboard (status film_ready). The film is always approved by a person in mint, never by the API.

video_keynullable string

Your key of the video, as sent.

versionnullable string

Version of the video, canonical (1.0.0 is returned as 1.0).

previous_version_idnullable string

Id of the film with the next lower version of the same video_key, or null.

is_latest_approved_versionboolean

true only if this film is approved and no higher, approved and not cancelled version of the same video_key exists.

languagenullable enum

Language of the film.

Possible values de en fr es it pt nl pl cs sk hu ro hr sl sv da no fi tr id vi el uk ru bg
templatenullable string

Key of the template used when the film was created.

settingsobject

Effective settings of the film in mint. Values that are not set (or that mint cannot express in the API) are null.

Show child attributes
formatnullable enum

Aspect ratio.

Possible values 16x9 9x16 1x1
style_idnullable string

Id of the style (see GET /styles).

style_revisionnullable integer

Revision of the style the film uses.

Minimum 1
brand_idnullable string

Effective brand (see GET /brands); null = no brand.

voice_idnullable string

Voice of the narration (may also be a voice from the mint voice library); null = none set yet.

voice_namenullable string

Name of the voice.

narration_modenullable enum

verbatim (default): narration_text is spoken word for word. smooth: mint polishes the language of narration_text and keeps its content. free: narration_text is the briefing; mint writes the narration freely (use target_duration_s for the length).

temponullable enum

Pace of the film.

Possible values presenting lively kinetic
freedomnullable enum

Creative freedom in percent.

Possible values 0 25 40 65 100
video_sharenullable enum

Share of moving video clips in percent.

Possible values 0 25 50 75 100
target_duration_snullable integer

Target duration in seconds (in steps of 6 seconds).

Minimum 1
categorynullable object

Category of the film in mint (see GET /categories), or null.

Show child attributes
objectstring
Always category
idstring

Id of the category.

namestring
external_keynullable string

Key of the connected system, if set.

parentnullable object

Top-level category of a subcategory; null for a top-level category.

Show child attributes
idstring
namestring
external_keynullable string
requested_bynullable objectPersonal data

The mint user from user_email of the request (a Person with kind user). This user is responsible for the film in mint and is notified when the storyboard is ready. Personal data.

Show child attributes
kindenum

Always user.

Possible values user
emailstringPersonal data

E-mail address (lower case).

namenullable stringPersonal data

Name of the user at the time the film was created.

metadataobject

Your metadata, as sent. mint never uses it for the film. Key order is kept in POST /films (first response), GET /films and GET /films/{id}; a replayed response may order keys differently.

approvalnullable object

The active approval of the film (only the approved original version is the film), or null.

Show child attributes
revisioninteger

Approved revision of the film.

Minimum 1
approved_atstring (date-time)

Time of the approval (UTC).

sha256nullable string

SHA-256 of the approved file (hex).

bytesnullable integer

Size of the approved file in bytes.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

mimenullable string

Media type of the file, e.g. video/mp4.

has_subtitlesboolean

true if subtitles were frozen with this approval (subtitles_url).

approved_bynullable objectPersonal data

Who approved the film in mint (kind user, name and e-mail; email is null for approvals before 9 November 2026). Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

cancelled_atnullable string (date-time)

Time of the cancellation (UTC), or null.

created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

app_urlnullable string

Link to the film in mint (for people with access), or null.

file_urlnullable string

Path of the approved file (GET /films/{id}/file, relative to the host of the API), or null without an active approval.

subtitles_urlnullable string

Path of the subtitles of the approval (GET /films/{id}/subtitles.srt), or null if the approval has none.

revisionsarray of objects

Rendered revisions of the film, newest last (only in GET /films/{id}, without file links).

Show child attributes
revisioninteger

Number of the rendered revision.

Minimum 1
statusenum

rendering, ready or failed.

created_atnullable string (date-time)

Start of the render (UTC).

finished_atnullable string (date-time)

End of the render (UTC), null while rendering.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

has_moreboolean

true if more films may follow (also after a short or empty page when filtering by status).

next_cursornullable string

Pass as cursor to get the next page; null on the last page.

Errors 400 · 401 · 403 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films
curl "https://api.cream-ai.de/api/v1/films?status=approved&limit=20" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "film",
      "id": "k7m2xq9v4t8n1b5r3c6d0wza",
      "title": "Lesson 3: Market segmentation",
      "status": "approved",
      "stage": "approved",
      "attention_required": false,
      "notice": null,
      "source": "api",
      "automation": "storyboard",
      "video_key": "MKT101-lesson-03",
      "version": "1.0",
      "previous_version_id": null,
      "is_latest_approved_version": true,
      "language": "de",
      "template": "lesson-standard",
      "settings": {
        "format": "16x9",
        "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
        "style_revision": 4,
        "brand_id": "brand-northwind-x7k2p9",
        "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
        "voice_name": "Clara",
        "narration_mode": "verbatim",
        "tempo": "presenting",
        "freedom": 40,
        "video_share": 25,
        "target_duration_s": 180
      },
      "category": {
        "object": "category",
        "id": "rz3p8w1d6c0b",
        "name": "MKT101 Marketing basics",
        "external_key": "MKT101",
        "parent": {
          "id": "mk7t2q9x4v1n",
          "name": "Marketing",
          "external_key": "MKT"
        }
      },
      "requested_by": {
        "kind": "user",
        "email": "anna.schmidt@example.edu",
        "name": "Anna Schmidt"
      },
      "metadata": {
        "course_id": "MKT101",
        "lesson": 3
      },
      "approval": {
        "revision": 2,
        "approved_at": "2026-11-11T14:30:00Z",
        "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
        "bytes": 48213377,
        "duration_s": 184.6,
        "resolution": "1920x1080",
        "mime": "video/mp4",
        "has_subtitles": true,
        "approved_by": {
          "kind": "user",
          "name": "Anna Schmidt",
          "email": "anna.schmidt@example.edu"
        }
      },
      "cancelled_at": null,
      "created_at": "2026-11-10T08:00:00Z",
      "updated_at": "2026-11-11T14:30:00Z",
      "app_url": "https://app.cream-ai.de/editorial/k7m2xq9v4t8n1b5r3c6d0wza",
      "file_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file",
      "subtitles_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/subtitles.srt"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Cancel a film

POST/api/v1/films/{id}/cancel
View as Markdown

Cancels a film ordered through the API, also while mint is planning or producing it automatically, until the storyboard is ready. Running planning and production are stopped; costs that already occurred stay. Once the storyboard (or the film) is ready, the film can no longer be cancelled through the API: 409 not_cancellable with details.reason (for example not_api_film for projects created in mint, other_client if another API access ordered the film, storyboard_ready). Only the API access that ordered the film can cancel it, unless that access was revoked or expired. Cancelling again returns 200 with the cancelled film. A cancelled film frees its video_key and version: the same order then creates a new film.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Headers

Idempotency-Keystring

Optional unique key of this write request (1–128 visible ASCII characters). Retries with the same key return the stored response.

1–128 characters

Request body optional

reasonnullable string

Optional reason (at most 500 characters) for the cancellation.

Up to 500 characters

Returns

200

The cancelled film. Returns the film object.

Errors 400 · 401 · 403 · 404 · 409 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

Conflict (category_exists, external_key_exists, external_key_conflict, category_limit_reached, idempotency_in_progress, version_conflict, previous_version_creating, film_deleted, not_cancellable, file_unavailable, storyboard_not_ready, storyboard_not_current, timeline_outdated, preview_in_progress, preview_not_ready, preview_unsupported, feedback_queue_full, feedback_not_cancellable, feedback_not_retryable, feedback_busy, revision_locked, film_not_ready, film_busy, no_open_comments, comments_not_open, correction_in_progress, upload_quota_exceeded, film_cancelled).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/films/{id}/cancel
curl -X POST "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/cancel" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Lesson was removed from the course."
  }'
Response 200
{
  "object": "film",
  "id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "title": "Lesson 3: Market segmentation",
  "status": "cancelled",
  "stage": "cancelled",
  "attention_required": false,
  "notice": null,
  "source": "api",
  "automation": "storyboard",
  "video_key": "MKT101-lesson-03",
  "version": "1.0",
  "previous_version_id": null,
  "is_latest_approved_version": true,
  "language": "de",
  "template": "lesson-standard",
  "settings": {
    "format": "16x9",
    "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
    "style_revision": 4,
    "brand_id": "brand-northwind-x7k2p9",
    "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
    "voice_name": "Clara",
    "narration_mode": "verbatim",
    "tempo": "presenting",
    "freedom": 40,
    "video_share": 25,
    "target_duration_s": 180
  },
  "category": {
    "object": "category",
    "id": "rz3p8w1d6c0b",
    "name": "MKT101 Marketing basics",
    "external_key": "MKT101",
    "parent": {
      "id": "mk7t2q9x4v1n",
      "name": "Marketing",
      "external_key": "MKT"
    }
  },
  "requested_by": {
    "kind": "user",
    "email": "anna.schmidt@example.edu",
    "name": "Anna Schmidt"
  },
  "metadata": {
    "course_id": "MKT101",
    "lesson": 3
  },
  "approval": null,
  "cancelled_at": "2026-11-10T08:05:10Z",
  "created_at": "2026-11-10T08:00:00Z",
  "updated_at": "2026-11-10T08:05:10Z",
  "app_url": "https://app.cream-ai.de/editorial/k7m2xq9v4t8n1b5r3c6d0wza",
  "file_url": null,
  "subtitles_url": null,
  "revisions": [],
  "latest_revision": null
}

Download the approved film file

GET/api/v1/films/{id}/file
View as Markdown

Downloads the approved file of a film ordered through the API (only the approved original version; format and language versions are not part of v1). The response is the file as video/mp4 with a strong ETag (the SHA-256 of the file, the same as approval.sha256 of the current approval). Compare it with the SHA-256 of the downloaded bytes. Resume an interrupted download with Range: bytes=<from>- and If-Range: <ETag>: 206 with the rest, or 200 with the whole file if the approval changed. A single range is supported; several ranges or an invalid one return the whole file. A range behind the end returns 416 range_not_satisfiable. With If-None-Match: <ETag> the response is 304 without a body when the approval is unchanged. HEAD returns the headers only. The download always returns the approval that is active now. If an event is older than the current approval, the ETag differs from data.approval.sha256 of the event; then the ETag counts. 404 not_approved: the film has no active approval (never approved or revoked). 409 file_unavailable: the file is missing or does not match the approval; mint is informed, retry later. 503 with Retry-After: mint is checking the file or is briefly unavailable, retry after the given seconds. At most a few downloads per company run at the same time (429 rate_limited with details.reason parallel_downloads and Retry-After). Downloads are free of credits.

Path parameters

idstringRequired

Id of the film (id from POST /films, GET /films or film_id of an event).

Headers

Rangestring

One byte range, e.g. bytes=33554432-.

If-Rangestring

The ETag of the first response; the range only applies if it still matches.

If-None-Matchstring

The ETag you already have; 304 if unchanged.

Returns

200

The whole approved file.

ETag Strong ETag: the SHA-256 of the file in quotes. Compare it with the SHA-256 of the downloaded bytes.
Accept-Ranges bytes: downloads can be resumed with Range.
Content-Length Length of the body in bytes.
Content-Disposition attachment; filename="<film_id>_r<revision>.<ext>".
Cache-Control no-store, no-transform.
206

The requested part of the approved file.

ETag Strong ETag: the SHA-256 of the file in quotes. Compare it with the SHA-256 of the downloaded bytes.
Accept-Ranges bytes: downloads can be resumed with Range.
Content-Length Length of the body in bytes.
Content-Disposition attachment; filename="<film_id>_r<revision>.<ext>".
Cache-Control no-store, no-transform.
Content-Range bytes <from>-<to>/<size>.
304

Unchanged (the ETag from If-None-Match still matches).

ETag Strong ETag: the SHA-256 of the file in quotes. Compare it with the SHA-256 of the downloaded bytes.
Errors 401 · 403 · 404 · 409 · 416 · 429 · 500 · 503
401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found) or not approved (not_approved).

409

The approved file is not available (file_unavailable). mint is informed; retry later.

416

The range is behind the end of the file (range_not_satisfiable).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}/file
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -o film.mp4
Response 200
HTTP/1.1 200 OK
Content-Type: video/mp4
X-Request-Id: req_5b2e8f1a4c7d0e3b6a9f2c5d8e1b4a7c
ETag: "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
Accept-Ranges: bytes
Content-Length: 48213377
Content-Disposition: attachment; filename="k7m2xq9v4t8n1b5r3c6d0wza_r2.mp4"
Cache-Control: no-store, no-transform

<binary MP4 data>

Download the subtitles of the approval

GET/api/v1/films/{id}/subtitles.srt
View as Markdown

Downloads the subtitles (SubRip) that were frozen with the active approval of a film ordered through the API. Only the subtitles of the approval are returned, never a newer state: 404 subtitles_not_available if the approval has none (subtitles_url of the film is then null). ETag, If-None-Match, Range and HEAD work as for the film file.

Path parameters

idstringRequired

Id of the film (id from POST /films, GET /films or film_id of an event).

Headers

Rangestring

One byte range.

If-Rangestring

The ETag of the first response.

If-None-Matchstring

The ETag you already have; 304 if unchanged.

Returns

200

The subtitles (UTF-8).

ETag Strong ETag: the SHA-256 of the file in quotes. Compare it with the SHA-256 of the downloaded bytes.
Accept-Ranges bytes: downloads can be resumed with Range.
Content-Length Length of the body in bytes.
Content-Disposition attachment; filename="<film_id>_r<revision>.<ext>".
Cache-Control no-store, no-transform.
206

The requested part of the subtitles.

ETag Strong ETag: the SHA-256 of the file in quotes. Compare it with the SHA-256 of the downloaded bytes.
Accept-Ranges bytes: downloads can be resumed with Range.
Content-Length Length of the body in bytes.
Content-Disposition attachment; filename="<film_id>_r<revision>.<ext>".
Cache-Control no-store, no-transform.
Content-Range bytes <from>-<to>/<size>.
304

Unchanged.

ETag Strong ETag: the SHA-256 of the file in quotes. Compare it with the SHA-256 of the downloaded bytes.
Errors 401 · 403 · 404 · 409 · 416 · 429 · 500 · 503
401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found), not approved (not_approved) or the approval has no subtitles (subtitles_not_available).

409

The subtitles are not available (file_unavailable). mint is informed; retry later.

416

The range is behind the end of the file (range_not_satisfiable).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}/subtitles.srt
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/subtitles.srt" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -o film.srt
Response 200
HTTP/1.1 200 OK
Content-Type: application/x-subrip
X-Request-Id: req_5b2e8f1a4c7d0e3b6a9f2c5d8e1b4a7c
ETag: "9f2c4e6a8b0d1f3e5a7c9b1d3f5e7a9c2b4d6f8e0a1c3e5b7d9f1a3c5e7b9d2f"
Accept-Ranges: bytes
Content-Length: 6214
Content-Disposition: attachment; filename="k7m2xq9v4t8n1b5r3c6d0wza_r2.srt"
Cache-Control: no-store, no-transform

1
00:00:00,000 --> 00:00:04,200
Not every customer wants the same thing.

While mint produces a film, GET /films/{id}/progress shows how far it is: the production steps (narration, timeline, images and clips, scenes, film), how many scenes are done and a rough estimate of the remaining time. Reading the progress is free. Use it for a progress bar while a person is watching; for everything else, the event feed is enough.

Attributes

objectstring
Always film_progress
film_idstring

Id of the film.

statusenum

Status of the film, as in GET /films/{id}.

Possible values briefing in_production storyboard_ready film_ready approved cancelled
stagenullable enum

Detailed stage, as in GET /films/{id}, or null if unknown. New values may be added within v1.

attention_requiredboolean

true if a person needs to act in mint, as in GET /films/{id}.

productionnullable object

The latest production of the film, or null if there is none yet.

Show child attributes
statusenum

queued, running, storyboard_ready (the storyboard is ready, no film is rendering), film_rendering, film_ready, failed or cancelled. New values may be added within v1.

phaseenum

Current step (see steps[].id).

Possible values audio timeline media scenes film
storyboard_versionnullable integer

Version of the storyboard this production works on.

Minimum 1
started_atnullable string (date-time)

Start of the production (UTC).

updated_atnullable string (date-time)

Last change of the production (UTC).

stepsarray of objects

Steps of the production in order; empty without a production.

Show child attributes
idenum

audio, timeline, media, scenes or film. New values may be added within v1.

statusenum
Possible values waiting running done failed
partsarray of objects

Parts of the step with their own progress (only present if the step has parts).

Show child attributes
idstring

Stable technical id of the part.

labelstring

Display text of the part as shown in mint (German).

statusenum
Possible values waiting running done failed
progressnullable number

Progress from 0 to 1, or null if unknown.

0–1
started_atnullable string (date-time)

Start of the part (UTC), or null.

scenesnullable object

Scene counts of the current storyboard, or null without a production.

Show child attributes
totalinteger

Scenes of the current storyboard (sum of the other counts).

doneinteger

Finished in the current state.

renderinginteger

Being created or changed right now.

pendinginteger

Not started yet.

outdatedinteger

Finished, but in an older state of the storyboard.

failedinteger

The last change of the scene failed.

estimatenullable object

Rough estimate of the remaining time, or null.

Show child attributes
remaining_sinteger

Estimated remaining seconds.

confidenceenum

low or medium. Treat it as a rough guess.

basisenum

scene_rate: from the scenes finished so far; film_render: from the progress of the film render. New values may be added within v1.

The film progress object
{
  "object": "film_progress",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "status": "in_production",
  "stage": "storyboard_in_progress",
  "attention_required": false,
  "production": {
    "status": "running",
    "phase": "scenes",
    "storyboard_version": 1,
    "started_at": "2026-11-10T08:00:04Z",
    "updated_at": "2026-11-10T08:14:52Z"
  },
  "steps": [
    {
      "id": "scenes",
      "status": "running",
      "parts": [
        {
          "id": "scene-07",
          "label": "Scene 7",
          "status": "running",
          "progress": 0.6,
          "started_at": "2026-11-10T08:13:30Z"
        }
      ]
    }
  ],
  "scenes": {
    "total": 14,
    "done": 9,
    "rendering": 2,
    "pending": 3,
    "outdated": 0,
    "failed": 0
  },
  "estimate": {
    "remaining_s": 240,
    "confidence": "medium",
    "basis": "scene_rate"
  }
}

Get the production progress of a film

GET/api/v1/films/{id}/progress
View as Markdown

The production progress of a film ordered through the API. Reading it is free of credits and changes nothing. status, stage and attention_required are the same as in GET /films/{id}. Without a production (the film is still in the briefing, or mint has not started yet) production is null, steps is empty and scenes and estimate are null. steps follow the production in mint: audio (narration), timeline, media (images and clips), scenes (rendering the storyboard scenes) and film (rendering the film). A step can have parts with their own progress (0–1). scenes counts every scene of the current storyboard exactly once: done (current and finished), rendering (being created or changed right now), failed (the last change of this scene failed), outdated (finished, but an older state) and pending (the rest). estimate is a rough guess of the remaining seconds, only while scenes or the film are rendering and once there is enough data; otherwise null. Do not use it for deadlines. The response can be up to 5 seconds old. Poll at most every few seconds, or follow the event feed. Unknown ids, projects created in mint, films of other companies and films deleted in mint return 404 not_found. New values in steps[].id, production.phase and production.status may be added within v1.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Returns

200

The progress of the film. Returns the film progress object.

Errors 401 · 403 · 404 · 429 · 500 · 503
401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

The film was not found (not_found): unknown id, a project created in mint, a film of another company or a film deleted in mint.

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}/progress
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/progress" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "film_progress",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "status": "in_production",
  "stage": "storyboard_in_progress",
  "attention_required": false,
  "production": {
    "status": "running",
    "phase": "scenes",
    "storyboard_version": 1,
    "started_at": "2026-11-10T08:00:04Z",
    "updated_at": "2026-11-10T08:14:52Z"
  },
  "steps": [
    {
      "id": "scenes",
      "status": "running",
      "parts": [
        {
          "id": "scene-07",
          "label": "Scene 7",
          "status": "running",
          "progress": 0.6,
          "started_at": "2026-11-10T08:13:30Z"
        }
      ]
    }
  ],
  "scenes": {
    "total": 14,
    "done": 9,
    "rendering": 2,
    "pending": 3,
    "outdated": 0,
    "failed": 0
  },
  "estimate": {
    "remaining_s": 240,
    "confidence": "medium",
    "basis": "scene_rate"
  }
}

Events tell you what happened to films ordered through the API, in a fixed order per company. See Event feed for the recommended way to consume them.

Endpoints

Attributes

objectstring
Always event
idstring

Stable id of the event (evt_<seq>).

seqinteger

Position in the feed; grows within your company (with gaps).

Minimum 1
typestring

Type of the event. Known types: film.created, film.status_changed, film.storyboard_ready, film.approved, film.approval_revoked, film.cancelled, film.deleted, film.progress, feedback.updated, storyboard.preview_ready, operation.completed. New types may be added.

occurred_atstring (date-time)

Time of the change (UTC).

film_idnullable string

Id of the film.

dataobject

Snapshot at the time of the event: status (after the event), previous_status, approval, and the person who triggered the event (requested_by, cancelled_by, approval.approved_by, approval.revoked_by; personal data).

Show child attributes
statusnullable enum

Status of the film after the event.

Possible values briefing in_production storyboard_ready film_ready approved cancelled
previous_statusnullable string

Status before the event (null if the feed did not know the film yet).

approvalobject

Snapshot of the approval at the time of the event (in film.approved complete, in film.approval_revoked only id and revision).

Show child attributes
idstring

Id of the approval.

revisionnullable integer

Approved revision of the film.

Minimum 1
approved_atnullable string (date-time)

Time of the approval (UTC).

sha256nullable string

SHA-256 of the approved file (hex).

bytesnullable integer

Size of the approved file in bytes.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

mimenullable string

Media type of the file.

has_subtitlesboolean

true if subtitles were frozen with this approval.

approved_bynullable objectPersonal data

film.approved: who approved the film in mint. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

revoked_bynullable objectPersonal data

film.approval_revoked: who revoked the approval in mint. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

requested_bynullable objectPersonal data

film.created: the mint user from user_email of the order. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

cancelled_bynullable objectPersonal data

film.cancelled: the API access that cancelled the film (kind api). Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

filmnullable film object

The current film (as GET /films/{id}, without revisions); null if it was deleted. Only present with the scope films:read.

Show child attributes
objectstring
Always film
idstring

Id of the film in mint.

titlestring

Title as it is in mint now (people can change it there).

statusenum

briefing: created in mint, nothing is running (for example with automation: none). in_production: mint is planning or producing the storyboard (or the film). storyboard_ready: the storyboard is ready for review in mint. With automation: storyboard the film stops here until a person continues in mint. film_ready: the film is rendered and waits for approval by a person in mint. approved: a person approved the film in mint. cancelled: the film was cancelled. New values may be added within v1.

stagenullable enum

Detailed stage as shown in the mint project list, or null if unknown. New values may be added within v1.

Possible values briefing style voice ready_to_plan planning storyboard_in_progress storyboard_review film_rendering film_ready approved paused error cancelled
attention_requiredboolean

true if a person needs to act in mint (see notice).

noticenullable object

Why a person needs to act in mint, or null. Codes: production_paused (“Production is paused in mint. Someone needs to resume it.”), production_failed (“Production failed in mint. Someone needs to check it.”), planning_failed (“Planning the storyboard failed in mint. Someone needs to check it.”), automation_failed (“The automatic storyboard could not be completed. Someone needs to continue in mint.”), insufficient_credits (“The company does not have enough credits. Someone needs to add credits and continue in mint.”), automation_disabled (“Automatic production is currently switched off. Someone needs to continue in mint.”).

Show child attributes
codeenum
Possible values production_paused production_failed planning_failed automation_failed insufficient_credits automation_disabled
messagestring

Short English text (may change).

sourceenum

api: ordered through the API; app: reserved for projects created in mint (not returned in v1).

automationnullable enum

none: mint only creates the film with its briefing; people continue in mint. storyboard (default): mint plans and produces the storyboard automatically and stops at storyboard_ready for review. film: mint also renders the film without stopping at the storyboard (status film_ready). The film is always approved by a person in mint, never by the API.

video_keynullable string

Your key of the video, as sent.

versionnullable string

Version of the video, canonical (1.0.0 is returned as 1.0).

previous_version_idnullable string

Id of the film with the next lower version of the same video_key, or null.

is_latest_approved_versionboolean

true only if this film is approved and no higher, approved and not cancelled version of the same video_key exists.

languagenullable enum

Language of the film.

Possible values de en fr es it pt nl pl cs sk hu ro hr sl sv da no fi tr id vi el uk ru bg
templatenullable string

Key of the template used when the film was created.

settingsobject

Effective settings of the film in mint. Values that are not set (or that mint cannot express in the API) are null.

Show child attributes
formatnullable enum

Aspect ratio.

Possible values 16x9 9x16 1x1
style_idnullable string

Id of the style (see GET /styles).

style_revisionnullable integer

Revision of the style the film uses.

Minimum 1
brand_idnullable string

Effective brand (see GET /brands); null = no brand.

voice_idnullable string

Voice of the narration (may also be a voice from the mint voice library); null = none set yet.

voice_namenullable string

Name of the voice.

narration_modenullable enum

verbatim (default): narration_text is spoken word for word. smooth: mint polishes the language of narration_text and keeps its content. free: narration_text is the briefing; mint writes the narration freely (use target_duration_s for the length).

temponullable enum

Pace of the film.

Possible values presenting lively kinetic
freedomnullable enum

Creative freedom in percent.

Possible values 0 25 40 65 100
video_sharenullable enum

Share of moving video clips in percent.

Possible values 0 25 50 75 100
target_duration_snullable integer

Target duration in seconds (in steps of 6 seconds).

Minimum 1
categorynullable object

Category of the film in mint (see GET /categories), or null.

Show child attributes
objectstring
Always category
idstring

Id of the category.

namestring
external_keynullable string

Key of the connected system, if set.

parentnullable object

Top-level category of a subcategory; null for a top-level category.

Show child attributes
idstring
namestring
external_keynullable string
requested_bynullable objectPersonal data

The mint user from user_email of the request (a Person with kind user). This user is responsible for the film in mint and is notified when the storyboard is ready. Personal data.

Show child attributes
kindenum

Always user.

Possible values user
emailstringPersonal data

E-mail address (lower case).

namenullable stringPersonal data

Name of the user at the time the film was created.

metadataobject

Your metadata, as sent. mint never uses it for the film. Key order is kept in POST /films (first response), GET /films and GET /films/{id}; a replayed response may order keys differently.

approvalnullable object

The active approval of the film (only the approved original version is the film), or null.

Show child attributes
revisioninteger

Approved revision of the film.

Minimum 1
approved_atstring (date-time)

Time of the approval (UTC).

sha256nullable string

SHA-256 of the approved file (hex).

bytesnullable integer

Size of the approved file in bytes.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

mimenullable string

Media type of the file, e.g. video/mp4.

has_subtitlesboolean

true if subtitles were frozen with this approval (subtitles_url).

approved_bynullable objectPersonal data

Who approved the film in mint (kind user, name and e-mail; email is null for approvals before 9 November 2026). Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

cancelled_atnullable string (date-time)

Time of the cancellation (UTC), or null.

created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

app_urlnullable string

Link to the film in mint (for people with access), or null.

file_urlnullable string

Path of the approved file (GET /films/{id}/file, relative to the host of the API), or null without an active approval.

subtitles_urlnullable string

Path of the subtitles of the approval (GET /films/{id}/subtitles.srt), or null if the approval has none.

revisionsarray of objects

Rendered revisions of the film, newest last (only in GET /films/{id}, without file links).

Show child attributes
revisioninteger

Number of the rendered revision.

Minimum 1
statusenum

rendering, ready or failed.

created_atnullable string (date-time)

Start of the render (UTC).

finished_atnullable string (date-time)

End of the render (UTC), null while rendering.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

The event object
{
  "object": "event",
  "id": "evt_10482",
  "seq": 10482,
  "type": "film.approved",
  "occurred_at": "2026-11-11T14:30:00Z",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "data": {
    "status": "approved",
    "previous_status": "film_ready",
    "approval": {
      "id": "apr_20931",
      "revision": 2,
      "approved_at": "2026-11-11T14:30:00Z",
      "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
      "bytes": 48213377,
      "duration_s": 184.6,
      "resolution": "1920x1080",
      "mime": "video/mp4",
      "has_subtitles": true,
      "approved_by": {
        "kind": "user",
        "name": "Anna Schmidt",
        "email": "anna.schmidt@example.edu"
      },
      "revoked_by": null
    },
    "requested_by": {
      "kind": "user",
      "name": "Anna Schmidt",
      "email": "anna.schmidt@example.edu"
    },
    "cancelled_by": null
  },
  "film": {
    "object": "film",
    "id": "k7m2xq9v4t8n1b5r3c6d0wza",
    "title": "Lesson 3: Market segmentation",
    "status": "approved",
    "stage": "approved",
    "attention_required": false,
    "notice": null,
    "source": "api",
    "automation": "storyboard",
    "video_key": "MKT101-lesson-03",
    "version": "1.0",
    "previous_version_id": null,
    "is_latest_approved_version": true,
    "language": "de",
    "template": "lesson-standard",
    "settings": {
      "format": "16x9",
      "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
      "style_revision": 4,
      "brand_id": "brand-northwind-x7k2p9",
      "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
      "voice_name": "Clara",
      "narration_mode": "verbatim",
      "tempo": "presenting",
      "freedom": 40,
      "video_share": 25,
      "target_duration_s": 180
    },
    "category": {
      "object": "category",
      "id": "rz3p8w1d6c0b",
      "name": "MKT101 Marketing basics",
      "external_key": "MKT101",
      "parent": {
        "id": "mk7t2q9x4v1n",
        "name": "Marketing",
        "external_key": "MKT"
      }
    },
    "requested_by": {
      "kind": "user",
      "email": "anna.schmidt@example.edu",
      "name": "Anna Schmidt"
    },
    "metadata": {
      "course_id": "MKT101",
      "lesson": 3
    },
    "approval": {
      "revision": 2,
      "approved_at": "2026-11-11T14:30:00Z",
      "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
      "bytes": 48213377,
      "duration_s": 184.6,
      "resolution": "1920x1080",
      "mime": "video/mp4",
      "has_subtitles": true,
      "approved_by": {
        "kind": "user",
        "name": "Anna Schmidt",
        "email": "anna.schmidt@example.edu"
      }
    },
    "cancelled_at": null,
    "created_at": "2026-11-10T08:00:00Z",
    "updated_at": "2026-11-11T14:30:00Z",
    "app_url": "https://app.cream-ai.de/editorial/k7m2xq9v4t8n1b5r3c6d0wza",
    "file_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file",
    "subtitles_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/subtitles.srt"
  }
}

Read the event feed

GET/api/v1/events
View as Markdown

The event feed of your company: every change of a film ordered through the API that matters to you, in a fixed order. Each event has a seq that grows within your company. Read the feed with after = next_after of the previous page (start with 0) and store next_after only after you processed the page. Duplicates (at least once) can be recognized by id. data is a snapshot at the time of the event. film is the current state of the film (as GET /films/{id}, without revisions) and is only present if the API key also has the scope films:read; it is null for a film that was deleted in mint. Types: film.created, film.status_changed (every change of status), film.storyboard_ready (once per storyboard), film.approved, film.approval_revoked, film.cancelled, film.deleted. A specific event comes before its film.status_changed. New types may be added within v1; ignore types you do not know. mint keeps events for 180 days. An after older than that returns 410 cursor_expired; an after ahead of the feed (for example from another mint server) returns 400 invalid_cursor. In both cases start again: note latest_seq, read GET /films?status=approved, then continue with after = the noted latest_seq. mint writes events together with the change. In rare cases an event comes up to 10 minutes late; intermediate states can then be missing, the final state is always reported.

Query parameters

afterstring

Return events with a seq greater than this (next_after of the previous page). Default 0 (from the oldest kept event).

Default 0
typesstring

Comma-separated list of event types (default: all). Known types: film.created, film.status_changed, film.storyboard_ready, film.approved, film.approval_revoked, film.cancelled, film.deleted, film.progress, feedback.updated, storyboard.preview_ready, operation.completed.

sourceenum

api: films ordered through the API (default and currently the only value).

Default api
Possible values api
limitinteger

Page size (1–100).

Default 50 · 1–100

Returns

200

One page of events.

Show response attributes
objectstring
Always list
dataarray of event objects
Show child attributes
objectstring
Always event
idstring

Stable id of the event (evt_<seq>).

seqinteger

Position in the feed; grows within your company (with gaps).

Minimum 1
typestring

Type of the event. Known types: film.created, film.status_changed, film.storyboard_ready, film.approved, film.approval_revoked, film.cancelled, film.deleted, film.progress, feedback.updated, storyboard.preview_ready, operation.completed. New types may be added.

occurred_atstring (date-time)

Time of the change (UTC).

film_idnullable string

Id of the film.

dataobject

Snapshot at the time of the event: status (after the event), previous_status, approval, and the person who triggered the event (requested_by, cancelled_by, approval.approved_by, approval.revoked_by; personal data).

Show child attributes
statusnullable enum

Status of the film after the event.

Possible values briefing in_production storyboard_ready film_ready approved cancelled
previous_statusnullable string

Status before the event (null if the feed did not know the film yet).

approvalobject

Snapshot of the approval at the time of the event (in film.approved complete, in film.approval_revoked only id and revision).

Show child attributes
idstring

Id of the approval.

revisionnullable integer

Approved revision of the film.

Minimum 1
approved_atnullable string (date-time)

Time of the approval (UTC).

sha256nullable string

SHA-256 of the approved file (hex).

bytesnullable integer

Size of the approved file in bytes.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

mimenullable string

Media type of the file.

has_subtitlesboolean

true if subtitles were frozen with this approval.

approved_bynullable objectPersonal data

film.approved: who approved the film in mint. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

revoked_bynullable objectPersonal data

film.approval_revoked: who revoked the approval in mint. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

requested_bynullable objectPersonal data

film.created: the mint user from user_email of the order. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

cancelled_bynullable objectPersonal data

film.cancelled: the API access that cancelled the film (kind api). Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

filmnullable film object

The current film (as GET /films/{id}, without revisions); null if it was deleted. Only present with the scope films:read.

Show child attributes
objectstring
Always film
idstring

Id of the film in mint.

titlestring

Title as it is in mint now (people can change it there).

statusenum

briefing: created in mint, nothing is running (for example with automation: none). in_production: mint is planning or producing the storyboard (or the film). storyboard_ready: the storyboard is ready for review in mint. With automation: storyboard the film stops here until a person continues in mint. film_ready: the film is rendered and waits for approval by a person in mint. approved: a person approved the film in mint. cancelled: the film was cancelled. New values may be added within v1.

stagenullable enum

Detailed stage as shown in the mint project list, or null if unknown. New values may be added within v1.

Possible values briefing style voice ready_to_plan planning storyboard_in_progress storyboard_review film_rendering film_ready approved paused error cancelled
attention_requiredboolean

true if a person needs to act in mint (see notice).

noticenullable object

Why a person needs to act in mint, or null. Codes: production_paused (“Production is paused in mint. Someone needs to resume it.”), production_failed (“Production failed in mint. Someone needs to check it.”), planning_failed (“Planning the storyboard failed in mint. Someone needs to check it.”), automation_failed (“The automatic storyboard could not be completed. Someone needs to continue in mint.”), insufficient_credits (“The company does not have enough credits. Someone needs to add credits and continue in mint.”), automation_disabled (“Automatic production is currently switched off. Someone needs to continue in mint.”).

Show child attributes
codeenum
Possible values production_paused production_failed planning_failed automation_failed insufficient_credits automation_disabled
messagestring

Short English text (may change).

sourceenum

api: ordered through the API; app: reserved for projects created in mint (not returned in v1).

automationnullable enum

none: mint only creates the film with its briefing; people continue in mint. storyboard (default): mint plans and produces the storyboard automatically and stops at storyboard_ready for review. film: mint also renders the film without stopping at the storyboard (status film_ready). The film is always approved by a person in mint, never by the API.

video_keynullable string

Your key of the video, as sent.

versionnullable string

Version of the video, canonical (1.0.0 is returned as 1.0).

previous_version_idnullable string

Id of the film with the next lower version of the same video_key, or null.

is_latest_approved_versionboolean

true only if this film is approved and no higher, approved and not cancelled version of the same video_key exists.

languagenullable enum

Language of the film.

Possible values de en fr es it pt nl pl cs sk hu ro hr sl sv da no fi tr id vi el uk ru bg
templatenullable string

Key of the template used when the film was created.

settingsobject

Effective settings of the film in mint. Values that are not set (or that mint cannot express in the API) are null.

Show child attributes
formatnullable enum

Aspect ratio.

Possible values 16x9 9x16 1x1
style_idnullable string

Id of the style (see GET /styles).

style_revisionnullable integer

Revision of the style the film uses.

Minimum 1
brand_idnullable string

Effective brand (see GET /brands); null = no brand.

voice_idnullable string

Voice of the narration (may also be a voice from the mint voice library); null = none set yet.

voice_namenullable string

Name of the voice.

narration_modenullable enum

verbatim (default): narration_text is spoken word for word. smooth: mint polishes the language of narration_text and keeps its content. free: narration_text is the briefing; mint writes the narration freely (use target_duration_s for the length).

temponullable enum

Pace of the film.

Possible values presenting lively kinetic
freedomnullable enum

Creative freedom in percent.

Possible values 0 25 40 65 100
video_sharenullable enum

Share of moving video clips in percent.

Possible values 0 25 50 75 100
target_duration_snullable integer

Target duration in seconds (in steps of 6 seconds).

Minimum 1
categorynullable object

Category of the film in mint (see GET /categories), or null.

Show child attributes
objectstring
Always category
idstring

Id of the category.

namestring
external_keynullable string

Key of the connected system, if set.

parentnullable object

Top-level category of a subcategory; null for a top-level category.

Show child attributes
idstring
namestring
external_keynullable string
requested_bynullable objectPersonal data

The mint user from user_email of the request (a Person with kind user). This user is responsible for the film in mint and is notified when the storyboard is ready. Personal data.

Show child attributes
kindenum

Always user.

Possible values user
emailstringPersonal data

E-mail address (lower case).

namenullable stringPersonal data

Name of the user at the time the film was created.

metadataobject

Your metadata, as sent. mint never uses it for the film. Key order is kept in POST /films (first response), GET /films and GET /films/{id}; a replayed response may order keys differently.

approvalnullable object

The active approval of the film (only the approved original version is the film), or null.

Show child attributes
revisioninteger

Approved revision of the film.

Minimum 1
approved_atstring (date-time)

Time of the approval (UTC).

sha256nullable string

SHA-256 of the approved file (hex).

bytesnullable integer

Size of the approved file in bytes.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

mimenullable string

Media type of the file, e.g. video/mp4.

has_subtitlesboolean

true if subtitles were frozen with this approval (subtitles_url).

approved_bynullable objectPersonal data

Who approved the film in mint (kind user, name and e-mail; email is null for approvals before 9 November 2026). Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

cancelled_atnullable string (date-time)

Time of the cancellation (UTC), or null.

created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

app_urlnullable string

Link to the film in mint (for people with access), or null.

file_urlnullable string

Path of the approved file (GET /films/{id}/file, relative to the host of the API), or null without an active approval.

subtitles_urlnullable string

Path of the subtitles of the approval (GET /films/{id}/subtitles.srt), or null if the approval has none.

revisionsarray of objects

Rendered revisions of the film, newest last (only in GET /films/{id}, without file links).

Show child attributes
revisioninteger

Number of the rendered revision.

Minimum 1
statusenum

rendering, ready or failed.

created_atnullable string (date-time)

Start of the render (UTC).

finished_atnullable string (date-time)

End of the render (UTC), null while rendering.

duration_snullable number

Duration in seconds.

resolutionnullable string

Resolution, e.g. 1920x1080.

has_moreboolean

true if more events follow right away.

next_afterinteger

Pass as after to continue. Store it only after you processed the page.

latest_seqinteger

The newest position of the feed of your company (for a restart, see above).

Errors 400 · 401 · 403 · 410 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

410

This position is no longer kept (cursor_expired, details.min_after, details.latest_seq). Start again with latest_seq and GET /films?status=approved.

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/events
curl "https://api.cream-ai.de/api/v1/events?after=10480&types=film.approved,film.approval_revoked,film.deleted" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "event",
      "id": "evt_10482",
      "seq": 10482,
      "type": "film.approved",
      "occurred_at": "2026-11-11T14:30:00Z",
      "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
      "data": {
        "status": "approved",
        "previous_status": "film_ready",
        "approval": {
          "id": "apr_20931",
          "revision": 2,
          "approved_at": "2026-11-11T14:30:00Z",
          "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
          "bytes": 48213377,
          "duration_s": 184.6,
          "resolution": "1920x1080",
          "mime": "video/mp4",
          "has_subtitles": true,
          "approved_by": {
            "kind": "user",
            "name": "Anna Schmidt",
            "email": "anna.schmidt@example.edu"
          },
          "revoked_by": null
        },
        "requested_by": {
          "kind": "user",
          "name": "Anna Schmidt",
          "email": "anna.schmidt@example.edu"
        },
        "cancelled_by": null
      },
      "film": {
        "object": "film",
        "id": "k7m2xq9v4t8n1b5r3c6d0wza",
        "title": "Lesson 3: Market segmentation",
        "status": "approved",
        "stage": "approved",
        "attention_required": false,
        "notice": null,
        "source": "api",
        "automation": "storyboard",
        "video_key": "MKT101-lesson-03",
        "version": "1.0",
        "previous_version_id": null,
        "is_latest_approved_version": true,
        "language": "de",
        "template": "lesson-standard",
        "settings": {
          "format": "16x9",
          "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
          "style_revision": 4,
          "brand_id": "brand-northwind-x7k2p9",
          "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
          "voice_name": "Clara",
          "narration_mode": "verbatim",
          "tempo": "presenting",
          "freedom": 40,
          "video_share": 25,
          "target_duration_s": 180
        },
        "category": {
          "object": "category",
          "id": "rz3p8w1d6c0b",
          "name": "MKT101 Marketing basics",
          "external_key": "MKT101",
          "parent": {
            "id": "mk7t2q9x4v1n",
            "name": "Marketing",
            "external_key": "MKT"
          }
        },
        "requested_by": {
          "kind": "user",
          "email": "anna.schmidt@example.edu",
          "name": "Anna Schmidt"
        },
        "metadata": {
          "course_id": "MKT101",
          "lesson": 3
        },
        "approval": {
          "revision": 2,
          "approved_at": "2026-11-11T14:30:00Z",
          "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
          "bytes": 48213377,
          "duration_s": 184.6,
          "resolution": "1920x1080",
          "mime": "video/mp4",
          "has_subtitles": true,
          "approved_by": {
            "kind": "user",
            "name": "Anna Schmidt",
            "email": "anna.schmidt@example.edu"
          }
        },
        "cancelled_at": null,
        "created_at": "2026-11-10T08:00:00Z",
        "updated_at": "2026-11-11T14:30:00Z",
        "app_url": "https://app.cream-ai.de/editorial/k7m2xq9v4t8n1b5r3c6d0wza",
        "file_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/file",
        "subtitles_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/subtitles.srt"
      }
    }
  ],
  "has_more": false,
  "next_after": 10482,
  "latest_seq": 10482
}

A storyboard preview is an MP4 (1280x720) of the current storyboard: the scene clips in film order with the voice-over and a visible watermark. Use it to review a film in your own system before it is finished, for example together with feedback on single scenes.

  • Each new preview costs credits (currently 100). A preview of an unchanged storyboard is reused and not charged again.
  • Creating a preview is a long-running operation: you get 202 and poll the operation.
  • Previews are kept for a limited time (expires_at); after that, request a new one.
  • A preview is never the approved film.

Attributes

objectstring
Always storyboard_preview
idstring

Id of the preview.

film_idstring

Id of the film.

statusenum
Possible values queued rendering ready failed expired
storyboard_versioninteger

Version of the storyboard the preview shows.

currentboolean

true if every scene is current and the preview belongs to the current storyboard.

duration_snullable number

Duration in seconds (planned until ready).

fpsnullable number

Frames per second.

resolutionnullable string

Resolution, e.g. 1280x720.

bytesnullable integer

Size of the file in bytes (when ready).

sha256nullable string

SHA-256 of the file (hex, when ready); the same as the ETag of the download.

watermarkboolean

true: the preview carries a visible watermark.

scenesarray of objects
Show child attributes
nrinteger

Number of the scene.

Minimum 1
start_snumber

Start of the scene in the preview (seconds).

end_snumber

End of the scene in the preview (seconds).

stateenum

current: clip of the current version; stale: clip of an earlier version (marked „outdated“); missing: no clip yet (dark panel).

file_urlnullable string

Path of the file download (when ready).

created_atstring (date-time)

Time of the request (UTC).

ready_atnullable string (date-time)

Time the preview became ready (UTC).

expires_atnullable string (date-time)

Time the preview expires (UTC); afterwards the file is deleted.

The storyboard preview object
{
  "object": "storyboard_preview",
  "id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "status": "ready",
  "storyboard_version": 1,
  "current": true,
  "duration_s": 181.2,
  "fps": 25,
  "resolution": "1280x720",
  "bytes": 18342210,
  "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
  "watermark": true,
  "scenes": [
    {
      "nr": 1,
      "start_s": 0,
      "end_s": 12.4,
      "state": "current"
    },
    {
      "nr": 2,
      "start_s": 12.4,
      "end_s": 25.9,
      "state": "current"
    }
  ],
  "file_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/storyboard-preview/file?preview_id=pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
  "created_at": "2026-11-10T08:25:00Z",
  "ready_at": "2026-11-10T08:27:41Z",
  "expires_at": "2026-11-24T08:27:41Z"
}

Request a storyboard preview (costs credits)

POST/api/v1/films/{id}/storyboard-preview
View as Markdown

Has mint create a storyboard preview of the film: one MP4 (1280x720) with the current scene clips in film order, the voice-over and a visible watermark „PREVIEW · Scene n“. It is not the finished film and never replaces the approval in mint. The preview is optional. Each new preview costs credits according to the mint price list (currently 100 credits); mint books them on the company in the name of the user from user_email of the order, after the preview is ready. A failed preview is not charged. When requesting, the company must have enough credits for this preview and for all of its previews that are still being created or not charged yet; otherwise the response is 402 insufficient_credits with details.required_credits (the credits needed for all of them) and nothing is created. The response is an operation (202 Accepted, Location: /api/v1/operations/{id}). Poll it until status is succeeded; result.url then points to the preview. If a ready preview of exactly the same storyboard state exists, the response is 200 with an operation that has already succeeded and reused: true; it points to that preview and is not charged again. If the same state is being created right now, the response is 202 with reused: true. Scenes that are not up to date are shown as „outdated“ or as a dark panel „is still being rendered“. With require_current: true the request is rejected with 409 storyboard_not_current (details.scenes) as long as a scene is not up to date. 409 storyboard_not_ready: the film has no storyboard yet. 409 preview_in_progress (details.operation_id): a preview of another state of this film is still being created; retry later. 409 preview_unsupported: previews are not available for this kind of film. 409 film_cancelled: the film was cancelled through the API; existing previews can still be read. 503 with details.feature storyboard_preview: previews are switched off right now. Rejections with a passing reason (storyboard_not_ready, preview_in_progress, insufficient_credits) are not stored under the Idempotency-Key: a retry with the same key runs again. The operation stays bound to its key: the same key with another request returns 422 idempotency_mismatch, also after 24 hours.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Headers

Idempotency-KeystringRequired

Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

1–128 characters

Request body optional

require_currentboolean

true: only create the preview if every scene is up to date (otherwise 409 storyboard_not_current). Default false: outdated and missing scenes are marked in the preview.

Default false

Returns

200

A ready preview of the same storyboard state exists (status succeeded, reused: true, not charged again), or the operation of this Idempotency-Key has already finished.

Location Path of the operation: /api/v1/operations/{id}.
Show response attributes
objectstring
Always operation
idstring
typeenum

Kind of operation. New types may be added within v1; ignore operations of unknown types.

Possible values storyboard.preview film.comments_apply
statusenum
Possible values queued running succeeded failed
created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

resultnullable object
Show child attributes
objectstring
idstring
urlstring
errornullable object
Show child attributes
codestring
messagestring
reusedboolean

true if the request reuses a preview of the same storyboard state (ready or being created); it is not charged again.

202

The preview is being created (or the same state is already being created, reused: true). Poll the operation from Location.

Location Path of the operation: /api/v1/operations/{id}.
Show response attributes
objectstring
Always operation
idstring
typeenum

Kind of operation. New types may be added within v1; ignore operations of unknown types.

Possible values storyboard.preview film.comments_apply
statusenum
Possible values queued running succeeded failed
created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

resultnullable object
Show child attributes
objectstring
idstring
urlstring
errornullable object
Show child attributes
codestring
messagestring
reusedboolean

true if the request reuses a preview of the same storyboard state (ready or being created); it is not charged again.

Errors 400 · 401 · 402 · 403 · 404 · 409 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

402

The company does not have enough credits for a preview (insufficient_credits, details.required_credits). Nothing was created; not stored under the Idempotency-Key.

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

No storyboard yet (storyboard_not_ready), scenes not up to date with require_current (storyboard_not_current, details.scenes), a preview of another state is being created (preview_in_progress, details.operation_id), previews not available for this film (preview_unsupported), the film was cancelled through the API (film_cancelled), or a request with this Idempotency-Key is still running (idempotency_in_progress).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/films/{id}/storyboard-preview
curl -X POST "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/storyboard-preview" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'
Response 202
{
  "object": "operation",
  "id": "op_4d9b2e7a1c6f3d8b5e0a2c7f9b4d1e6a",
  "type": "storyboard.preview",
  "status": "queued",
  "created_at": "2026-11-10T08:25:00Z",
  "updated_at": "2026-11-10T08:25:00Z",
  "result": null,
  "error": null,
  "reused": false
}

Get a storyboard preview

GET/api/v1/films/{id}/storyboard-preview
View as Markdown

Returns a storyboard preview of the film: without preview_id the newest one, otherwise the one with this id (result.id of the operation). status: queued, rendering, ready, failed or expired (previews are kept for a limited time, see expires_at). scenes shows the time range and state of each scene in the preview (current, stale = from an earlier version, missing = not rendered yet). current is true if every scene is up to date and the preview belongs to the current storyboard. Download the file with file_url as soon as status is ready.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Query parameters

preview_idstring

Id of the preview (result.id of the operation). Default: the newest preview of the film.

Returns

200

The storyboard preview. Returns the storyboard preview object.

Errors 400 · 401 · 403 · 404 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

The film or the preview was not found, or the film has no preview yet (not_found).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}/storyboard-preview
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/storyboard-preview" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "storyboard_preview",
  "id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "status": "ready",
  "storyboard_version": 1,
  "current": true,
  "duration_s": 181.2,
  "fps": 25,
  "resolution": "1280x720",
  "bytes": 18342210,
  "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
  "watermark": true,
  "scenes": [
    {
      "nr": 1,
      "start_s": 0,
      "end_s": 12.4,
      "state": "current"
    },
    {
      "nr": 2,
      "start_s": 12.4,
      "end_s": 25.9,
      "state": "current"
    }
  ],
  "file_url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/storyboard-preview/file?preview_id=pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
  "created_at": "2026-11-10T08:25:00Z",
  "ready_at": "2026-11-10T08:27:41Z",
  "expires_at": "2026-11-24T08:27:41Z"
}

Download the MP4 of a storyboard preview

GET/api/v1/films/{id}/storyboard-preview/file
View as Markdown

Downloads the MP4 of a storyboard preview (without preview_id the newest one). The preview is not approved and carries a watermark. The response is video/mp4 with a strong ETag (the SHA-256 of the file in quotes, the same as sha256 of the preview). Resume an interrupted download with Range: bytes=<from>- and If-Range: <ETag>. A single range is supported; several or invalid ranges return the whole file; a range behind the end returns 416 range_not_satisfiable. With If-None-Match: <ETag> the response is 304 without a body. HEAD returns the headers only. 409 preview_not_ready: the preview is not ready yet. 410 preview_expired: the preview has expired; request a new one. 409 file_unavailable: the file is currently not available; retry later. Downloads are free of credits.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Query parameters

preview_idstring

Id of the preview. Default: the newest preview of the film.

Headers

Rangestring

One byte range, e.g. bytes=1048576-.

If-Rangestring

The ETag of the first response; the range only applies if it still matches.

If-None-Matchstring

The ETag you already have; 304 if unchanged.

Returns

200

The whole file.

ETag Strong ETag: the SHA-256 of the file in quotes (the same as sha256 of the preview).
Accept-Ranges bytes: downloads can be resumed with Range.
Content-Length Length of the body in bytes.
Content-Disposition attachment; filename="storyboard-v<storyboard_version>.mp4".
Cache-Control no-store, no-transform.
206

The requested part of the file.

ETag Strong ETag: the SHA-256 of the file in quotes (the same as sha256 of the preview).
Accept-Ranges bytes: downloads can be resumed with Range.
Content-Length Length of the body in bytes.
Content-Disposition attachment; filename="storyboard-v<storyboard_version>.mp4".
Cache-Control no-store, no-transform.
Content-Range bytes <from>-<to>/<size>.
304

Unchanged (the ETag from If-None-Match still matches).

ETag Strong ETag: the SHA-256 of the file in quotes (the same as sha256 of the preview).
Errors 400 · 401 · 403 · 404 · 409 · 410 · 416 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

The film or the preview was not found, or the film has no preview yet (not_found).

409

The preview is not ready yet (preview_not_ready) or its file is currently not available (file_unavailable).

410

The preview has expired (preview_expired). Request a new one.

416

The range is behind the end of the file (range_not_satisfiable).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}/storyboard-preview/file
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/storyboard-preview/file" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -o preview.mp4
Response 200
HTTP/1.1 200 OK
Content-Type: video/mp4
X-Request-Id: req_5b2e8f1a4c7d0e3b6a9f2c5d8e1b4a7c
ETag: "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
Accept-Ranges: bytes
Content-Length: 18342210
Content-Disposition: attachment; filename="storyboard-v1.mp4"
Cache-Control: no-store, no-transform

<binary MP4 data>

Feedback changes scenes of the storyboard, like a message in the mint chat. Each entry names a scene (scene), a time (at_s) or both, and says what to change. mint plans and applies every entry on its own and never asks back.

  1. Optionally request a storyboard preview and refer to it with preview_id.
  2. Send one or more entries with POST /films/{id}/feedback. Attach images with uploads.
  3. Follow each entry: queued → applying → applied, or failed / discarded. Poll the entry or listen for feedback.updated events.
  4. A failed entry can be sent again with POST /films/{id}/feedback/{feedback_id}/retry.

Feedback can cost credits according to the mint price list. Redrawing a scene at a fixed price only happens with allow_redraw: true.

Attributes

objectstring
Always feedback
idstring
batch_idnullable string

Id of the request (id of the batch).

film_idstring

Id of the film.

scenenullable integer

Number of the scene.

Minimum 1
at_snullable number

Time from the request.

scene_offset_snullable number

Time within the scene (seconds from its start).

preview_idnullable string

Preview the time refers to.

storyboard_versionnullable integer

Storyboard version at the time of the request.

kindenum
Possible values text image layout general
messagestring

The feedback as sent.

regionnullable object

Area of the frame as fractions of width and height (0..1, origin top left). It is cut to the frame.

Show child attributes
xnumber
0–1
ynumber
0–1
wnumber

Width; the area must be greater than 0.

0–1
hnumber

Height; the area must be greater than 0.

0–1
pointnullable object

Point in the frame as fractions of width and height (0..1, origin top left).

Show child attributes
xnumber
0–1
ynumber
0–1
attachmentsarray of objects
Show child attributes
upload_idnullable string

Id of the upload.

media_idnullable string

Id of the file in the media of the film.

allow_redrawboolean
external_refnullable string
statusenum

queued: waiting for the scene; applying: being planned or applied (see stage); applied: the scene was changed; failed: not applied (see failure, retry possible); discarded: cancelled via the API or stopped in mint.

stagenullable enum

Only for applying: planning, waiting_for_scene (the scene is rendering), applying, rendering.

queue_reasonnullable enum

Only for queued: scene_busy (another change of the scene is running), storyboard_busy (the storyboard is being created), service_unavailable (retried automatically).

warningsarray of strings

Hints for the entry, e.g. timeline_may_be_outdated or scene_changed_since_preview. New values may be added.

resultnullable object
Show child attributes
summarynullable string

What mint changed (German, as in the mint chat).

actionnullable enum

Kind of change.

Possible values text image layout redraw regenerate none
storyboard_versionnullable integer

Storyboard version with the change.

renderenum

pending: the scene is not rendered yet; done: rendered.

failurenullable object
Show child attributes
codeenum

Reason (for failed and discarded). New codes may be added within v1; treat unknown codes like apply_failed.

messagestring

English description of the reason.

app_messagenullable string

The text mint shows in the chat (German), if any.

retry_allowedboolean

true for failed: POST …/retry is possible.

fixed_price_creditsnullable number

Only for redraw_required: the current fixed price of redrawing the scene from the mint price list (may change). Retry with allow_redraw: true to accept it.

sendernullable objectPersonal data

Who sent the entry: the API access that sent (or last retried) it. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

created_atstring (date-time)

Time of the request (UTC).

updated_atstring (date-time)

Last change of the state (UTC).

The feedback object
{
  "object": "feedback",
  "id": "fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e",
  "batch_id": "fbb_6e1c8a3f5d2b9e4a7c0f1d6b3e8a5c2f",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "scene": 4,
  "at_s": null,
  "scene_offset_s": null,
  "preview_id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
  "storyboard_version": 1,
  "kind": "text",
  "message": "Please write \"customer groups\" instead of \"target groups\" in the headline.",
  "region": null,
  "point": null,
  "attachments": [],
  "allow_redraw": false,
  "external_ref": "lms-review-8812",
  "status": "queued",
  "stage": null,
  "queue_reason": null,
  "warnings": [],
  "result": null,
  "failure": null,
  "sender": {
    "kind": "user",
    "name": "Anna Schmidt",
    "email": "anna.schmidt@example.edu"
  },
  "created_at": "2026-11-10T08:31:02Z",
  "updated_at": "2026-11-10T08:31:02Z"
}

Send feedback on scenes of the storyboard

POST/api/v1/films/{id}/feedback
View as Markdown

Sends feedback on scenes of the storyboard, like a message in the mint chat. mint plans and applies each entry on its own; it never asks back but decides on the most plausible reading. Approving the film stays with a person in mint. Each entry names a scene (scene), a time in the film (at_s) or both. With preview_id the time refers to that storyboard preview; without it, to the current timeline of the film. Several entries for the same scene are applied one after the other in the order of entries. The entries are queued (status: queued) and handed over as soon as the scene is free. Poll GET /films/{id}/feedback/{feedback_id} or listen for feedback.updated events. Credits: planning and rendering cost credits according to the mint price list, booked on the company in the name of the user from user_email of the order. A redraw of a scene at a fixed price only happens with allow_redraw: true. If the company does not have enough credits, the response is 402 insufficient_credits and nothing is created. Attachments are upload ids of your company (POST /uploads). The request is all or nothing: if one entry is invalid, no entry is created (field names the entry, e.g. entries[1].message). The batch stays bound to its Idempotency-Key: the same key with the same request returns the same entries (also after 24 hours), with another request 422 idempotency_mismatch. Rejections with a passing reason (storyboard_not_ready, insufficient_credits) are not stored under the key: a retry with the same key runs again. A film cancelled through the API (status: cancelled) takes no more feedback: 409 film_cancelled. Its feedback can still be read and cancelled.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Headers

Idempotency-KeystringRequired

Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

1–128 characters

Request body

preview_idstring

Storyboard preview the times (at_s) refer to. It must belong to the current storyboard of the film.

entriesarray of objectsRequired
Up to 20 items
Show child attributes
sceneinteger

Number of the scene in the current storyboard.

Minimum 1
at_snumber

Time in the film (or in the preview from preview_id) in seconds; it selects the scene at that time.

kindenum

What the feedback is about. timing and voice are not supported (400 feedback_kind_unsupported).

Default general
messagestringRequired

The feedback in your words (3 to 20000 characters after trimming; at most 100000 characters per request).

3–20,000 characters
regionobject

Area of the frame as fractions of width and height (0..1, origin top left). It is cut to the frame.

Show child attributes
xnumberRequired
0–1
ynumberRequired
0–1
wnumberRequired

Width; the area must be greater than 0.

0–1
hnumberRequired

Height; the area must be greater than 0.

0–1
pointobject

Point in the frame as fractions of width and height (0..1, origin top left).

Show child attributes
xnumberRequired
0–1
ynumberRequired
0–1
attachmentsarray of strings

Upload ids of your company (at most 4 per entry, 20 different per request). Unknown or foreign uploads: 400 upload_not_found; expired: 410 upload_expired.

Up to 4 items
allow_redrawboolean

true: mint may redraw the scene at a fixed price if the change needs it. Otherwise such an entry fails with redraw_required.

Default false
external_refstring

Your own reference (e.g. a ticket id); returned unchanged and in feedback.updated events.

1–128 characters

Returns

202

The entries were queued (or the entries of this Idempotency-Key are returned again).

Show response attributes
objectstring
Always feedback_batch
idstring

Id of the request; bound to its Idempotency-Key.

film_idstring

Id of the film.

dataarray of feedback objects

The entries in the order of entries.

Show child attributes
objectstring
Always feedback
idstring
batch_idnullable string

Id of the request (id of the batch).

film_idstring

Id of the film.

scenenullable integer

Number of the scene.

Minimum 1
at_snullable number

Time from the request.

scene_offset_snullable number

Time within the scene (seconds from its start).

preview_idnullable string

Preview the time refers to.

storyboard_versionnullable integer

Storyboard version at the time of the request.

kindenum
Possible values text image layout general
messagestring

The feedback as sent.

regionnullable object

Area of the frame as fractions of width and height (0..1, origin top left). It is cut to the frame.

Show child attributes
xnumber
0–1
ynumber
0–1
wnumber

Width; the area must be greater than 0.

0–1
hnumber

Height; the area must be greater than 0.

0–1
pointnullable object

Point in the frame as fractions of width and height (0..1, origin top left).

Show child attributes
xnumber
0–1
ynumber
0–1
attachmentsarray of objects
Show child attributes
upload_idnullable string

Id of the upload.

media_idnullable string

Id of the file in the media of the film.

allow_redrawboolean
external_refnullable string
statusenum

queued: waiting for the scene; applying: being planned or applied (see stage); applied: the scene was changed; failed: not applied (see failure, retry possible); discarded: cancelled via the API or stopped in mint.

stagenullable enum

Only for applying: planning, waiting_for_scene (the scene is rendering), applying, rendering.

queue_reasonnullable enum

Only for queued: scene_busy (another change of the scene is running), storyboard_busy (the storyboard is being created), service_unavailable (retried automatically).

warningsarray of strings

Hints for the entry, e.g. timeline_may_be_outdated or scene_changed_since_preview. New values may be added.

resultnullable object
Show child attributes
summarynullable string

What mint changed (German, as in the mint chat).

actionnullable enum

Kind of change.

Possible values text image layout redraw regenerate none
storyboard_versionnullable integer

Storyboard version with the change.

renderenum

pending: the scene is not rendered yet; done: rendered.

failurenullable object
Show child attributes
codeenum

Reason (for failed and discarded). New codes may be added within v1; treat unknown codes like apply_failed.

messagestring

English description of the reason.

app_messagenullable string

The text mint shows in the chat (German), if any.

retry_allowedboolean

true for failed: POST …/retry is possible.

fixed_price_creditsnullable number

Only for redraw_required: the current fixed price of redrawing the scene from the mint price list (may change). Retry with allow_redraw: true to accept it.

sendernullable objectPersonal data

Who sent the entry: the API access that sent (or last retried) it. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

created_atstring (date-time)

Time of the request (UTC).

updated_atstring (date-time)

Last change of the state (UTC).

Errors 400 · 401 · 402 · 403 · 404 · 409 · 410 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

402

The company does not have enough credits (insufficient_credits). Nothing was created; not stored under the Idempotency-Key.

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

The film was not found, or the preview from preview_id was not found (not_found, field: preview_id).

409

The film was cancelled through the API (film_cancelled), no storyboard yet (storyboard_not_ready), the timeline no longer matches (timeline_outdated, details.reason: preview_from_previous_storyboard or scene_boundaries_changed), too many open entries for this film (feedback_queue_full, details.open, details.limit), or a request with this Idempotency-Key is still running (idempotency_in_progress).

410

An attachment has expired (upload_expired, field names it). Upload the file again.

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch, details.batch_id), or a scene or time is not in the current storyboard (scene_not_found, field names the entry).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/films/{id}/feedback
curl -X POST "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/feedback" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "preview_id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
    "entries": [
      {
        "scene": 4,
        "kind": "text",
        "message": "Please write \"customer groups\" instead of \"target groups\" in the headline.",
        "external_ref": "lms-review-8812"
      }
    ]
  }'
Response 202
{
  "object": "feedback_batch",
  "id": "fbb_6e1c8a3f5d2b9e4a7c0f1d6b3e8a5c2f",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "data": [
    {
      "object": "feedback",
      "id": "fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e",
      "batch_id": "fbb_6e1c8a3f5d2b9e4a7c0f1d6b3e8a5c2f",
      "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
      "scene": 4,
      "at_s": null,
      "scene_offset_s": null,
      "preview_id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
      "storyboard_version": 1,
      "kind": "text",
      "message": "Please write \"customer groups\" instead of \"target groups\" in the headline.",
      "region": null,
      "point": null,
      "attachments": [],
      "allow_redraw": false,
      "external_ref": "lms-review-8812",
      "status": "queued",
      "stage": null,
      "queue_reason": null,
      "warnings": [],
      "result": null,
      "failure": null,
      "sender": {
        "kind": "user",
        "name": "Anna Schmidt",
        "email": "anna.schmidt@example.edu"
      },
      "created_at": "2026-11-10T08:31:02Z",
      "updated_at": "2026-11-10T08:31:02Z"
    }
  ]
}

Get a feedback entry

GET/api/v1/films/{id}/feedback/{feedback_id}
View as Markdown

Returns one feedback entry with its current state.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

feedback_idstringRequired

Id of the feedback entry (id from the feedback object).

Returns

200

The feedback entry. Returns the feedback object.

Errors 401 · 403 · 404 · 429 · 500 · 503
401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}/feedback/{feedback_id}
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/feedback/fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "feedback",
  "id": "fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e",
  "batch_id": "fbb_6e1c8a3f5d2b9e4a7c0f1d6b3e8a5c2f",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "scene": 4,
  "at_s": null,
  "scene_offset_s": null,
  "preview_id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
  "storyboard_version": 1,
  "kind": "text",
  "message": "Please write \"customer groups\" instead of \"target groups\" in the headline.",
  "region": null,
  "point": null,
  "attachments": [],
  "allow_redraw": false,
  "external_ref": "lms-review-8812",
  "status": "applied",
  "stage": null,
  "queue_reason": null,
  "warnings": [],
  "result": {
    "summary": "Headline changed to \"Customer groups\".",
    "action": "text",
    "storyboard_version": 2,
    "render": "done"
  },
  "failure": null,
  "sender": {
    "kind": "user",
    "name": "Anna Schmidt",
    "email": "anna.schmidt@example.edu"
  },
  "created_at": "2026-11-10T08:31:02Z",
  "updated_at": "2026-11-10T08:36:18Z"
}

List the feedback entries of a film

GET/api/v1/films/{id}/feedback
View as Markdown

Lists the feedback entries of the film, newest first. Filter with status; the filter uses the state of the last feedback.updated event, the objects always show the current state.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Query parameters

statusenum

Only entries with this status.

Possible values queued applying applied failed discarded
cursorstring

Opaque cursor from next_cursor of the previous page.

Up to 2,048 characters
limitinteger

Page size (1–100).

Default 50 · 1–100

Returns

200

One page of feedback entries.

Show response attributes
objectstring
Always list
dataarray of feedback objects
Show child attributes
objectstring
Always feedback
idstring
batch_idnullable string

Id of the request (id of the batch).

film_idstring

Id of the film.

scenenullable integer

Number of the scene.

Minimum 1
at_snullable number

Time from the request.

scene_offset_snullable number

Time within the scene (seconds from its start).

preview_idnullable string

Preview the time refers to.

storyboard_versionnullable integer

Storyboard version at the time of the request.

kindenum
Possible values text image layout general
messagestring

The feedback as sent.

regionnullable object

Area of the frame as fractions of width and height (0..1, origin top left). It is cut to the frame.

Show child attributes
xnumber
0–1
ynumber
0–1
wnumber

Width; the area must be greater than 0.

0–1
hnumber

Height; the area must be greater than 0.

0–1
pointnullable object

Point in the frame as fractions of width and height (0..1, origin top left).

Show child attributes
xnumber
0–1
ynumber
0–1
attachmentsarray of objects
Show child attributes
upload_idnullable string

Id of the upload.

media_idnullable string

Id of the file in the media of the film.

allow_redrawboolean
external_refnullable string
statusenum

queued: waiting for the scene; applying: being planned or applied (see stage); applied: the scene was changed; failed: not applied (see failure, retry possible); discarded: cancelled via the API or stopped in mint.

stagenullable enum

Only for applying: planning, waiting_for_scene (the scene is rendering), applying, rendering.

queue_reasonnullable enum

Only for queued: scene_busy (another change of the scene is running), storyboard_busy (the storyboard is being created), service_unavailable (retried automatically).

warningsarray of strings

Hints for the entry, e.g. timeline_may_be_outdated or scene_changed_since_preview. New values may be added.

resultnullable object
Show child attributes
summarynullable string

What mint changed (German, as in the mint chat).

actionnullable enum

Kind of change.

Possible values text image layout redraw regenerate none
storyboard_versionnullable integer

Storyboard version with the change.

renderenum

pending: the scene is not rendered yet; done: rendered.

failurenullable object
Show child attributes
codeenum

Reason (for failed and discarded). New codes may be added within v1; treat unknown codes like apply_failed.

messagestring

English description of the reason.

app_messagenullable string

The text mint shows in the chat (German), if any.

retry_allowedboolean

true for failed: POST …/retry is possible.

fixed_price_creditsnullable number

Only for redraw_required: the current fixed price of redrawing the scene from the mint price list (may change). Retry with allow_redraw: true to accept it.

sendernullable objectPersonal data

Who sent the entry: the API access that sent (or last retried) it. Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

created_atstring (date-time)

Time of the request (UTC).

updated_atstring (date-time)

Last change of the state (UTC).

has_moreboolean
next_cursornullable string

Pass as cursor to get the next page; null on the last page.

Errors 400 · 401 · 403 · 404 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}/feedback
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/feedback" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "feedback",
      "id": "fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e",
      "batch_id": "fbb_6e1c8a3f5d2b9e4a7c0f1d6b3e8a5c2f",
      "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
      "scene": 4,
      "at_s": null,
      "scene_offset_s": null,
      "preview_id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
      "storyboard_version": 1,
      "kind": "text",
      "message": "Please write \"customer groups\" instead of \"target groups\" in the headline.",
      "region": null,
      "point": null,
      "attachments": [],
      "allow_redraw": false,
      "external_ref": "lms-review-8812",
      "status": "queued",
      "stage": null,
      "queue_reason": null,
      "warnings": [],
      "result": null,
      "failure": null,
      "sender": {
        "kind": "user",
        "name": "Anna Schmidt",
        "email": "anna.schmidt@example.edu"
      },
      "created_at": "2026-11-10T08:31:02Z",
      "updated_at": "2026-11-10T08:31:02Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Cancel a feedback entry

POST/api/v1/films/{id}/feedback/{feedback_id}/cancel
View as Markdown

Cancels a feedback entry. A queued entry is removed from the queue. An entry being applied is stopped like „Stop“ in the mint chat: the scene gets its previous version back. Answers 200 with the entry (status: discarded, failure.code: cancelled_via_api). 409 feedback_busy (with Retry-After): the entry is being handed over or the change is being written right now; retry shortly. 409 feedback_not_cancellable: the entry is already applied, failed or discarded.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

feedback_idstringRequired

Id of the feedback entry (id from the feedback object).

Headers

Idempotency-KeystringRequired

Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

1–128 characters

Request body optional

No fields. Send an empty JSON object {} or no body.

Returns

200

The cancelled entry. Returns the feedback object.

Errors 400 · 401 · 403 · 404 · 409 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

The entry is being handed over or written right now (feedback_busy, with Retry-After), it can no longer be cancelled (feedback_not_cancellable), or a request with this Idempotency-Key is still running (idempotency_in_progress).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/films/{id}/feedback/{feedback_id}/cancel
curl -X POST "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/feedback/fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e/cancel" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'
Response 200
{
  "object": "feedback",
  "id": "fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e",
  "batch_id": "fbb_6e1c8a3f5d2b9e4a7c0f1d6b3e8a5c2f",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "scene": 4,
  "at_s": null,
  "scene_offset_s": null,
  "preview_id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
  "storyboard_version": 1,
  "kind": "text",
  "message": "Please write \"customer groups\" instead of \"target groups\" in the headline.",
  "region": null,
  "point": null,
  "attachments": [],
  "allow_redraw": false,
  "external_ref": "lms-review-8812",
  "status": "discarded",
  "stage": null,
  "queue_reason": null,
  "warnings": [],
  "result": null,
  "failure": {
    "code": "cancelled_via_api",
    "message": "The entry was cancelled through the API.",
    "app_message": null,
    "retry_allowed": false,
    "fixed_price_credits": null
  },
  "sender": {
    "kind": "user",
    "name": "Anna Schmidt",
    "email": "anna.schmidt@example.edu"
  },
  "created_at": "2026-11-10T08:31:02Z",
  "updated_at": "2026-11-10T08:33:40Z"
}

Retry a failed feedback entry

POST/api/v1/films/{id}/feedback/{feedback_id}/retry
View as Markdown

Sends a failed feedback entry again (only status: failed, otherwise 409 feedback_not_retryable). The entry is queued again under the calling API access. With allow_redraw: true mint may redraw the scene at a fixed price (see failure.fixed_price_credits of redraw_required). If the company does not have enough credits, the response is 402 insufficient_credits and the entry stays failed. A film cancelled through the API answers 409 film_cancelled.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

feedback_idstringRequired

Id of the feedback entry (id from the feedback object).

Headers

Idempotency-KeystringRequired

Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

1–128 characters

Request body optional

allow_redrawboolean

Change the permission to redraw the scene; without it the previous value applies.

Returns

202

The entry is queued again (status: queued). Returns the feedback object.

Errors 400 · 401 · 402 · 403 · 404 · 409 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

402

The company does not have enough credits (insufficient_credits). The entry stays failed; not stored under the Idempotency-Key.

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

Only failed entries can be retried (feedback_not_retryable), the film was cancelled through the API (film_cancelled), the entry changed at the same time (feedback_busy, with Retry-After), or a request with this Idempotency-Key is still running (idempotency_in_progress).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/films/{id}/feedback/{feedback_id}/retry
curl -X POST "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/feedback/fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e/retry" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "allow_redraw": true
  }'
Response 202
{
  "object": "feedback",
  "id": "fb_2a7d4c9e1b6f3a8d5c0e7b2f4a9d1c6e",
  "batch_id": "fbb_6e1c8a3f5d2b9e4a7c0f1d6b3e8a5c2f",
  "film_id": "k7m2xq9v4t8n1b5r3c6d0wza",
  "scene": 4,
  "at_s": null,
  "scene_offset_s": null,
  "preview_id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
  "storyboard_version": 1,
  "kind": "text",
  "message": "Please write \"customer groups\" instead of \"target groups\" in the headline.",
  "region": null,
  "point": null,
  "attachments": [],
  "allow_redraw": false,
  "external_ref": "lms-review-8812",
  "status": "queued",
  "stage": null,
  "queue_reason": null,
  "warnings": [],
  "result": null,
  "failure": null,
  "sender": {
    "kind": "user",
    "name": "Anna Schmidt",
    "email": "anna.schmidt@example.edu"
  },
  "created_at": "2026-11-10T08:31:02Z",
  "updated_at": "2026-11-10T08:31:02Z"
}

Comments belong to a finished film (a rendered revision). They mark a time and optionally a point in the picture, like comments in mint. A comment changes nothing by itself: POST /films/{id}/comments/apply applies the open comments and mint renders a new revision. The approval of the new revision stays with a person in mint.

at_s is the time in the film without the brand intro. If you play the approved file with an intro, subtract its length.

Attributes

objectstring
Always comment
idstring

Id of the comment (for comment_ids).

revisioninteger

Revision of the film the comment belongs to.

Minimum 1
at_snumber

Time in the film in seconds, without the brand intro.

xnullable number

Horizontal position in the picture (0 = left, 1 = right), if given.

0–1
ynullable number

Vertical position in the picture (0 = top, 1 = bottom), if given.

0–1
scenenullable integer

Number of the scene at at_s, if known.

Minimum 1
messagestring

Text of the comment.

Up to 2,000 characters
authornullable objectPersonal data

Who wrote the comment: a user in mint or an API access of your company (name = name of the access, email = null). Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

statusenum

open; in_progress while a new revision is being created from it; applied or not_applied afterwards; resolved if marked as done in mint. New values may be added within v1.

resultnullable object

Outcome of applying the comment (null until it was applied).

Show child attributes
revisionnullable integer

Revision that applied the comment.

Minimum 1
summarynullable string

What mint changed (text from mint, may be German).

reasonnullable string

Why mint did not apply it, if so (text from mint, may be German).

attachmentsarray of objects
Up to 5 items
Show child attributes
upload_idnullable string

Upload the attachment came from, if it was added through the API (POST /uploads); null for attachments added in mint.

media_idstring

Id of the attachment in the mint project (the same file always has the same id).

created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

The comment object
{
  "object": "comment",
  "id": "cmt_9QwX2rLm7Tz",
  "revision": 2,
  "at_s": 42.5,
  "x": 0.62,
  "y": 0.31,
  "scene": 5,
  "message": "The chart should show 2026, not 2025.",
  "author": {
    "kind": "api",
    "name": "Learning platform",
    "email": null
  },
  "status": "open",
  "result": null,
  "attachments": [
    {
      "upload_id": "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f",
      "media_id": "md_77120"
    }
  ],
  "created_at": "2026-11-11T15:02:19Z",
  "updated_at": "2026-11-11T15:02:19Z"
}

Comment on a film

POST/api/v1/films/{id}/comments
View as Markdown

Adds a comment to the latest finished revision of a film, at a time (at_s) and optionally a point (x, y) in the picture. at_s is the time in the film without the brand intro: if you play the approved file with an intro, subtract the intro length. message has 1–2000 characters. attachments are up to 5 ids of uploads of your company (POST /uploads); each use extends the upload's expiry. Comments are only possible on the latest finished revision: with revision set to an older one, or if a newer revision is finished in the meantime, the answer is 409 revision_locked with details.latest_revision. Without a finished film: 409 film_not_ready. The comment changes nothing by itself; POST /films/{id}/comments/apply applies the open comments as a new revision. A film cancelled through the API (status: cancelled) takes no more comments: 409 film_cancelled.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Headers

Idempotency-KeystringRequired

Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

1–128 characters

Request body

at_snumberRequired

Time in the film in seconds, without the brand intro.

xnullable number

Optional horizontal position (0–1).

0–1
ynullable number

Optional vertical position (0–1).

0–1
messagestringRequired

Text of the comment (trimmed).

1–2,000 characters
attachmentsnullable array of strings

Up to 5 upload ids of your company. Unknown ids and uploads of other companies: 400 upload_not_found; expired: 410 upload_expired.

Up to 5 items
revisionnullable integer

Optional: the revision you commented on. If it is not the latest finished one, the answer is 409 revision_locked.

Minimum 1

Returns

201

The new comment. Returns the comment object.

Errors 400 · 401 · 403 · 404 · 409 · 410 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

revision_locked (details.latest_revision), film_not_ready or film_cancelled (the film was cancelled through the API).

410

An upload in attachments has expired (upload_expired, field names it).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/films/{id}/comments
curl -X POST "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/comments" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "at_s": 42.5,
    "x": 0.62,
    "y": 0.31,
    "message": "The chart should show 2026, not 2025.",
    "attachments": [
      "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f"
    ]
  }'
Response 201
{
  "object": "comment",
  "id": "cmt_9QwX2rLm7Tz",
  "revision": 2,
  "at_s": 42.5,
  "x": 0.62,
  "y": 0.31,
  "scene": 5,
  "message": "The chart should show 2026, not 2025.",
  "author": {
    "kind": "api",
    "name": "Learning platform",
    "email": null
  },
  "status": "open",
  "result": null,
  "attachments": [
    {
      "upload_id": "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f",
      "media_id": "md_77120"
    }
  ],
  "created_at": "2026-11-11T15:02:19Z",
  "updated_at": "2026-11-11T15:02:19Z"
}

List the comments on a film

GET/api/v1/films/{id}/comments
View as Markdown

The comments on a finished film: by default on its latest finished revision, with revision on an earlier one. Sorted by at_s, then id. Comments come from the API and from users in mint; author tells who wrote them (personal data). Paging: pass revision together with cursor; if a newer revision was finished in between, a cursor without revision returns 400 invalid_cursor. 409 film_not_ready if the film has no finished revision yet; an unknown revision returns 404 not_found.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Query parameters

revisioninteger

Revision of the film (default: the latest finished one).

Minimum 1
limitinteger

Page size (1–100).

Default 50 · 1–100
cursorstring

Opaque cursor from next_cursor of the previous page.

Up to 2,048 characters

Returns

200

One page of comments (limit 1–100).

Show response attributes
objectstring
Always list
revisioninteger

Revision the comments belong to.

Minimum 1
dataarray of comment objects
Show child attributes
objectstring
Always comment
idstring

Id of the comment (for comment_ids).

revisioninteger

Revision of the film the comment belongs to.

Minimum 1
at_snumber

Time in the film in seconds, without the brand intro.

xnullable number

Horizontal position in the picture (0 = left, 1 = right), if given.

0–1
ynullable number

Vertical position in the picture (0 = top, 1 = bottom), if given.

0–1
scenenullable integer

Number of the scene at at_s, if known.

Minimum 1
messagestring

Text of the comment.

Up to 2,000 characters
authornullable objectPersonal data

Who wrote the comment: a user in mint or an API access of your company (name = name of the access, email = null). Personal data.

Show child attributes
kindenum

user: a mint user; api: an API access of your company.

namenullable stringPersonal data

Name of the user, or the name of the API access.

emailnullable stringPersonal data

E-mail address of the user (lower case), if known; always null for api.

statusenum

open; in_progress while a new revision is being created from it; applied or not_applied afterwards; resolved if marked as done in mint. New values may be added within v1.

resultnullable object

Outcome of applying the comment (null until it was applied).

Show child attributes
revisionnullable integer

Revision that applied the comment.

Minimum 1
summarynullable string

What mint changed (text from mint, may be German).

reasonnullable string

Why mint did not apply it, if so (text from mint, may be German).

attachmentsarray of objects
Up to 5 items
Show child attributes
upload_idnullable string

Upload the attachment came from, if it was added through the API (POST /uploads); null for attachments added in mint.

media_idstring

Id of the attachment in the mint project (the same file always has the same id).

created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

has_moreboolean
next_cursornullable string

Pass as cursor (with the same revision) to get the next page; null on the last page.

Errors 400 · 401 · 403 · 404 · 409 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

The film has no finished revision yet (film_not_ready).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/films/{id}/comments
curl "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/comments" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "revision": 2,
  "data": [
    {
      "object": "comment",
      "id": "cmt_9QwX2rLm7Tz",
      "revision": 2,
      "at_s": 42.5,
      "x": 0.62,
      "y": 0.31,
      "scene": 5,
      "message": "The chart should show 2026, not 2025.",
      "author": {
        "kind": "api",
        "name": "Learning platform",
        "email": null
      },
      "status": "open",
      "result": null,
      "attachments": [
        {
          "upload_id": "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f",
          "media_id": "md_77120"
        }
      ],
      "created_at": "2026-11-11T15:02:19Z",
      "updated_at": "2026-11-11T15:02:19Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Apply the comments (new revision)

POST/api/v1/films/{id}/comments/apply
View as Markdown

Applies the open comments of the latest finished revision (all, or the ones in comment_ids) as a new revision of the film, like “Apply comments” in mint. Answers 202 with an operation of type film.comments_apply (Location points to /api/v1/operations/{id}). When it has succeeded, result.id is the new revision. The same Idempotency-Key with the same body always returns the same operation, also after 24 hours; a different body returns 422 idempotency_mismatch. Errors before the start leave no operation: 409 film_cancelled (the film was cancelled through the API), 409 film_not_ready (no finished film or the film is being changed), 409 no_open_comments, 409 comments_not_open (details.comment_ids are no longer open), 409 correction_in_progress (a new revision is already being created; details.operation_id if it was started through the API), 409 film_busy (retry after Retry-After seconds), 402 insufficient_credits. Credits are booked like in mint, on the user who ordered the film (requested_by). If mint restarts while the comments are being applied, the operation fails with interrupted_by_restart; the comments are open again and you can apply them again with a new Idempotency-Key. The approval of a film always stays with a person in mint.

Path parameters

idstringRequired

Id of the film (id from POST /films or GET /films).

Headers

Idempotency-KeystringRequired

Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

1–128 characters

Request body optional

comment_idsnullable array of strings

Only these comments (all must still be open, otherwise 409 comments_not_open). Without it: all open comments of the latest finished revision.

Up to 200 items

Returns

202

The operation that creates the new revision (also for a repeated Idempotency-Key). Returns the operation object.

Location Path of the operation (/api/v1/operations/{id}).
Errors 400 · 401 · 402 · 403 · 404 · 409 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

402

Not enough credits for the new revision (insufficient_credits). Retry after topping up.

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

film_cancelled (the film was cancelled through the API), film_not_ready, no_open_comments, comments_not_open (details.comment_ids), correction_in_progress or film_busy (with Retry-After).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/films/{id}/comments/apply
curl -X POST "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/comments/apply" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'
Response 202
{
  "object": "operation",
  "id": "op_4d9b2e7a1c6f3d8b5e0a2c7f9b4d1e6a",
  "type": "film.comments_apply",
  "status": "queued",
  "created_at": "2026-11-11T15:10:00Z",
  "updated_at": "2026-11-11T15:10:00Z",
  "result": null,
  "error": null
}

Uploads bring your own images and videos into mint, for example a screenshot as an attachment of feedback or a comment. Send the raw bytes with the matching Content-Type. Uploads are free, belong to your company and expire 7 days after the last use. The file itself cannot be downloaded through the API.

Attributes

objectstring
Always upload
idstring

Id of the upload; use it in attachments.

filenamestring

Cleaned name of the file (display only).

Up to 160 characters
content_typeenum

Media type of the stored file (the real type of the content).

Possible values image/png image/jpeg image/webp video/mp4 video/quicktime video/webm
bytesinteger

Size in bytes.

Minimum 1
sha256string

SHA-256 of the file (hex).

created_atstring (date-time)

Time of the first upload (UTC).

expires_atstring (date-time)

Expiry (UTC): 7 days after creation or the last use.

The upload object
{
  "object": "upload",
  "id": "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f",
  "filename": "screenshot-scene-4.png",
  "content_type": "image/png",
  "bytes": 284113,
  "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
  "created_at": "2026-11-10T08:30:12Z",
  "expires_at": "2026-11-17T08:30:12Z"
}

Upload a file

POST/api/v1/uploads
View as Markdown

Uploads an image or a video for your company, to be used as an attachment of comments (attachments of POST /films/{id}/comments). Send the bytes of the file as the request body with its media type as Content-Type (image/png, image/jpeg, image/webp, video/mp4, video/quicktime, video/webm; no SVG) and a Content-Length (required; chunked uploads are rejected with 411 length_required). Images may be at most 25 MB, videos at most 200 MB. mint checks the content: if it does not match the media type, the answer is 415 file_content_mismatch. An image of another allowed type (for example a JPEG sent as image/png) is stored with its real type; content_type of the answer shows it. Uploading the same file (same bytes and type) again returns the existing upload with 200 and extends its expiry; a new upload returns 201. An upload expires 7 days after it was created or last used. Every API access of your company can use every upload of the company; other companies never see it. The file itself cannot be downloaded through the API. At most 2 uploads run at the same time per mint server: more return 429 rate_limited with details.reason parallel_uploads and Retry-After: 5. Each company has a storage quota for active uploads (409 upload_quota_exceeded with details.quota_bytes). A slow upload is aborted after 5 minutes (503). Uploads are free of credits.

Query parameters

filenamestring

Name of the file for display (control characters are removed, at most 160 characters). It is never used as a path.

Headers

Idempotency-KeystringRequired

Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

1–128 characters

Request body

The bytes of the file.

Content types: image/png image/jpeg image/webp video/mp4 video/quicktime video/webm

Returns

200

The same file was uploaded before: the existing upload (expiry extended). Returns the upload object.

Location Path of the upload (/api/v1/uploads/{id}).
201

The new upload. Returns the upload object.

Location Path of the upload (/api/v1/uploads/{id}).
Errors 400 · 401 · 403 · 409 · 411 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

409

The upload storage of your company is full (upload_quota_exceeded, details.quota_bytes).

411

Content-Length is missing (length_required).

413

The file is too large for its type (payload_too_large, details.max_bytes).

415

Media type not allowed (unsupported_media_type) or content does not match it (file_content_mismatch).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests or uploads at the same time (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/uploads
curl -X POST "https://api.cream-ai.de/api/v1/uploads?filename=screenshot-scene-4.png" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: image/png" \
  --data-binary @screenshot-scene-4.png
Response 201
{
  "object": "upload",
  "id": "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f",
  "filename": "screenshot-scene-4.png",
  "content_type": "image/png",
  "bytes": 284113,
  "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
  "created_at": "2026-11-10T08:30:12Z",
  "expires_at": "2026-11-17T08:30:12Z"
}

Get an upload

GET/api/v1/uploads/{id}
View as Markdown

The metadata of an upload of your company (never the file). Uploads of other companies and unknown ids return 404 not_found; expired uploads 410 upload_expired.

Path parameters

idstringRequired

Id of the upload (id from POST /uploads).

Returns

200

The upload. Returns the upload object.

Errors 401 · 403 · 404 · 410 · 429 · 500 · 503
401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

410

The upload has expired (upload_expired). Upload the file again.

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/uploads/{id}
curl "https://api.cream-ai.de/api/v1/uploads/upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "upload",
  "id": "upl_3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e1f",
  "filename": "screenshot-scene-4.png",
  "content_type": "image/png",
  "bytes": 284113,
  "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
  "created_at": "2026-11-10T08:30:12Z",
  "expires_at": "2026-11-17T08:30:12Z"
}

Operations represent work that takes longer than one request, such as creating a storyboard preview or applying comments. See Long-running operations.

Attributes

objectstring
Always operation
idstring
typeenum

Kind of operation. New types may be added within v1; ignore operations of unknown types.

Possible values storyboard.preview film.comments_apply
statusenum
Possible values queued running succeeded failed
created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

resultnullable object
Show child attributes
objectstring
idstring
urlstring
errornullable object
Show child attributes
codestring
messagestring
The operation object
{
  "object": "operation",
  "id": "op_4d9b2e7a1c6f3d8b5e0a2c7f9b4d1e6a",
  "type": "storyboard.preview",
  "status": "succeeded",
  "created_at": "2026-11-10T08:25:00Z",
  "updated_at": "2026-11-10T08:27:41Z",
  "result": {
    "object": "storyboard_preview",
    "id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
    "url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/storyboard-preview?preview_id=pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d"
  },
  "error": null
}

Get an operation

GET/api/v1/operations/{id}
View as Markdown

The current state of a long-running operation of your company, for example a storyboard preview (storyboard.preview) or applying comments to a finished film (film.comments_apply). The Location header of the request that started it points here. Poll until status is succeeded or failed (every few seconds is enough); the state is computed when you read it. result is set when the operation succeeded: storyboard_preview with the URL of the preview, or film_revision with the new revision (for example V3) and the URL of the film. error is set when it failed. Error codes: start_failed, preview_failed, correction_failed, interrupted_by_restart. start_failed: the operation could not be started; send the request again with a new Idempotency-Key. interrupted_by_restart: mint was restarted while applying the comments; they are open again and can be applied again. The scopes depend on the type (storyboard.preview: films:read + previews:read; film.comments_apply: films:read + films:revise; films:revise includes films:read). A key without them gets 403 forbidden_scope with details.required_scopes. Unknown ids, operations of other companies and operations of films deleted in mint return 404 not_found, before scopes are checked. New operation types may be added within v1; ignore operations of types you do not know.

Scopes by operation typestoryboard.preview: films:read + previews:read
film.comments_apply: films:read + films:revise

Path parameters

idstringRequired

Id of the operation (id of the Operation object, also at the end of the Location header).

Returns

200

The operation. Returns the operation object.

Errors 401 · 403 · 404 · 429 · 500 · 503
401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled). With forbidden_scope the key lacks a scope for this type of operation; details.required_scopes lists all scopes the type needs.

404

The operation was not found (not_found): unknown id, an operation of another company or of a film deleted in mint.

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/operations/{id}
curl "https://api.cream-ai.de/api/v1/operations/op_4d9b2e7a1c6f3d8b5e0a2c7f9b4d1e6a" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "operation",
  "id": "op_4d9b2e7a1c6f3d8b5e0a2c7f9b4d1e6a",
  "type": "storyboard.preview",
  "status": "succeeded",
  "created_at": "2026-11-10T08:25:00Z",
  "updated_at": "2026-11-10T08:27:41Z",
  "result": {
    "object": "storyboard_preview",
    "id": "pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d",
    "url": "https://api.cream-ai.de/api/v1/films/k7m2xq9v4t8n1b5r3c6d0wza/storyboard-preview?preview_id=pv_8c1e4a7d2b5f9e3c6a0d1b4e7f2a5c8d"
  },
  "error": null
}

Categories sort films in mint, in two levels: categories and subcategories. Link them to your own structure with external_key, for example a course code, and use that key when you order a film (category.external_key). Creating a category with an external_key that already exists returns the existing category.

Attributes

objectstring
Always category
idstring

Id of the category in mint.

namestring

Name, unique (case-insensitive) on its level.

1–80 characters
parent_idnullable string

Id of the top-level category of a subcategory; null for top-level categories.

external_keynullable string

Key of the connected system (e.g. a module number); null if not set.

1–100 characters
project_countinteger

Projects assigned directly to this category (not counting subcategories). Only with include=project_count.

childrenarray of category objects

Subcategories of a top-level category; always empty for subcategories.

The category object
{
  "object": "category",
  "id": "mk7t2q9x4v1n",
  "name": "Marketing",
  "parent_id": null,
  "external_key": "MKT",
  "project_count": 12,
  "children": []
}

List the category tree

GET/api/v1/categories
View as Markdown

Returns the categories of the company as a tree: top-level categories with their subcategories in children. Categories are a bounded two-level tree, so there is no paging (has_more is always false). With external_key only the category with this key is returned (zero or one entry, on any level). With include=project_count every category carries project_count; this loads all projects of the company and counts as a write request for the rate limits. The list is cached per company for up to 30 seconds, so changes made in mint (and on other servers) can take up to 30 seconds to appear; project_count values can be up to 30 seconds old.

Query parameters

external_keystring

Only the category with this external key (exact match, case-sensitive).

1–100 characters
includestring

Comma-separated extras. Allowed: project_count.

Returns

200

The category tree (or the category with the requested external key).

Show response attributes
objectstring
Always list
dataarray of category objects
Show child attributes
objectstring
Always category
idstring

Id of the category in mint.

namestring

Name, unique (case-insensitive) on its level.

1–80 characters
parent_idnullable string

Id of the top-level category of a subcategory; null for top-level categories.

external_keynullable string

Key of the connected system (e.g. a module number); null if not set.

1–100 characters
project_countinteger

Projects assigned directly to this category (not counting subcategories). Only with include=project_count.

childrenarray of category objects

Subcategories of a top-level category; always empty for subcategories.

has_moreboolean

Always false: the category tree is returned completely.

next_cursornullable string

Always null (no paging).

Errors 400 · 401 · 403 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/categories
curl "https://api.cream-ai.de/api/v1/categories" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "category",
      "id": "mk7t2q9x4v1n",
      "name": "Marketing",
      "parent_id": null,
      "external_key": "MKT",
      "children": [
        {
          "object": "category",
          "id": "rz3p8w1d6c0b",
          "name": "MKT101 Marketing basics",
          "parent_id": "mk7t2q9x4v1n",
          "external_key": "MKT101",
          "children": []
        }
      ]
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Create a category or subcategory

POST/api/v1/categories
View as Markdown

Creates a top-level category, or a subcategory with parent_id (only two levels). With external_key the request is safe to repeat: if a category with this key already exists (on any level, even with another parent_id), the response is 200 with that category and nothing is changed. The same name on the same level returns 409 category_exists with details.category_id. A company can have at most 500 categories (main and subcategories together); creating one more returns 409 category_limit_reached with details.limit.

Headers

Idempotency-KeystringRequired

Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

1–128 characters

Request body

namestringRequired

Name of the new category (trimmed; at most 80 characters, longer names are rejected).

1–80 characters
parent_idnullable string

Id of a top-level category to create a subcategory; omit or null for a top-level category.

external_keynullable string

Optional key of the connected system. Repeating the request with the same key returns the existing category (200).

1–100 characters

Returns

200

A category with this external key already exists; it is returned unchanged. Returns the category object.

201

The category was created. Returns the category object.

Errors 400 · 401 · 403 · 409 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

409

Conflict (category_exists, external_key_exists, external_key_conflict, category_limit_reached, idempotency_in_progress, version_conflict, previous_version_creating, film_deleted, not_cancellable, file_unavailable, storyboard_not_ready, storyboard_not_current, timeline_outdated, preview_in_progress, preview_not_ready, preview_unsupported, feedback_queue_full, feedback_not_cancellable, feedback_not_retryable, feedback_busy, revision_locked, film_not_ready, film_busy, no_open_comments, comments_not_open, correction_in_progress, upload_quota_exceeded, film_cancelled).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

POST /v1/categories
curl -X POST "https://api.cream-ai.de/api/v1/categories" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "MKT101 Marketing basics",
    "parent_id": "mk7t2q9x4v1n",
    "external_key": "MKT101"
  }'
Response 201
{
  "object": "category",
  "id": "rz3p8w1d6c0b",
  "name": "MKT101 Marketing basics",
  "parent_id": "mk7t2q9x4v1n",
  "external_key": "MKT101",
  "children": []
}

Rename a category or change its external key

PATCH/api/v1/categories/{id}
View as Markdown

Changes name and/or external_key (at least one). external_key: null removes the key. Moving a category (parent_id) is not supported in v1. A key used by another category returns 409 external_key_exists with details.category_id. If another request changed the same field of this category at the same time, the response is 503 service_unavailable with Retry-After; repeat the request.

Path parameters

idstringRequired

Id of the category.

Headers

Idempotency-Keystring

Optional unique key of this write request (1–128 visible ASCII characters). Retries with the same key return the stored response.

1–128 characters

Request body

namestring

New name.

1–80 characters
external_keynullable string

New external key; null removes it.

1–100 characters

Returns

200

The updated category. Returns the category object.

Errors 400 · 401 · 403 · 404 · 409 · 413 · 415 · 422 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

409

Conflict (category_exists, external_key_exists, external_key_conflict, category_limit_reached, idempotency_in_progress, version_conflict, previous_version_creating, film_deleted, not_cancellable, file_unavailable, storyboard_not_ready, storyboard_not_current, timeline_outdated, preview_in_progress, preview_not_ready, preview_unsupported, feedback_queue_full, feedback_not_cancellable, feedback_not_retryable, feedback_busy, revision_locked, film_not_ready, film_busy, no_open_comments, comments_not_open, correction_in_progress, upload_quota_exceeded, film_cancelled).

413

Request body too large (payload_too_large).

415

Request body is not JSON (unsupported_media_type).

422

Idempotency-Key reused with a different request (idempotency_mismatch).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

PATCH /v1/categories/{id}
curl -X PATCH "https://api.cream-ai.de/api/v1/categories/rz3p8w1d6c0b" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "MKT101 Marketing – basics"
  }'
Response 200
{
  "object": "category",
  "id": "rz3p8w1d6c0b",
  "name": "MKT101 Marketing – basics",
  "parent_id": "mk7t2q9x4v1n",
  "external_key": "MKT101",
  "children": []
}

Briefing templates are created by people in mint. A template fixes the look and the production settings of a film, so an order only needs the content. Use the key as template in POST /films.

Attributes

objectstring
Always template
idstring

Id of the template in mint.

keystring

Key of the template, unique in the company. Use it as template in POST /films.

namestring
languagenullable enum

Language the template sets, or null if it does not set one.

Possible values de en fr es it pt nl pl cs sk hu ro hr sl sv da no fi tr id vi el uk ru bg
settingsobject

Values the template sets, with the names and values of settings in POST /films. Fields the template does not set are missing.

Show child attributes
formatenum

Aspect ratio. Missing if the template does not set it.

Possible values 16x9 9x16 1x1
style_idstring

Id of the style. Missing if the template does not set it.

brand_idnullable string

Brand, or null for no brand. Missing: mint chooses the brand automatically.

voice_idnullable string

Voice, or null for the automatic voice. Missing if the template does not set it.

narration_modeenum

How the text is spoken. Missing if the template does not set it.

Possible values verbatim smooth free
tempoenum

Pace of the film. Missing if the template does not set it.

Possible values presenting lively kinetic
freedomenum

Creative freedom in percent. Missing if the template does not set it.

Possible values 0 25 40 65 100
video_shareenum

Share of moving video clips in percent. Missing if the template does not set it.

Possible values 0 25 50 75 100
target_duration_sinteger

Target duration in seconds (in steps of 6 seconds). Templates in mint allow up to 60 minutes; POST /films accepts at most 900 seconds in settings. Missing if the template does not set it.

Minimum 1
updated_atstring (date-time)

Last change of the template (UTC).

The template object
{
  "object": "template",
  "id": "tpl_51",
  "key": "lesson-standard",
  "name": "Lesson – standard",
  "language": "de",
  "settings": {
    "format": "16x9",
    "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
    "brand_id": "brand-northwind-x7k2p9",
    "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
    "narration_mode": "verbatim",
    "tempo": "presenting",
    "freedom": 40,
    "video_share": 25,
    "target_duration_s": 180
  },
  "updated_at": "2026-10-30T16:20:00Z"
}

List briefing templates

GET/api/v1/templates
View as Markdown

Active briefing templates of the company, created by people in mint. Use the key as template in POST /films. settings shows only the template values that POST /films also accepts in settings; the template may set further mint settings (for example music, depth or audience), which apply as well. Sorted by name (without case), then key. Changes in mint appear immediately.

Query parameters

limitinteger

Page size (1–100).

Default 50 · 1–100
cursorstring

Opaque cursor from next_cursor of the previous page.

Up to 2,048 characters

Returns

200

One page of the list.

Show response attributes
objectstring
Always list
dataarray of template objects
Show child attributes
objectstring
Always template
idstring

Id of the template in mint.

keystring

Key of the template, unique in the company. Use it as template in POST /films.

namestring
languagenullable enum

Language the template sets, or null if it does not set one.

Possible values de en fr es it pt nl pl cs sk hu ro hr sl sv da no fi tr id vi el uk ru bg
settingsobject

Values the template sets, with the names and values of settings in POST /films. Fields the template does not set are missing.

Show child attributes
formatenum

Aspect ratio. Missing if the template does not set it.

Possible values 16x9 9x16 1x1
style_idstring

Id of the style. Missing if the template does not set it.

brand_idnullable string

Brand, or null for no brand. Missing: mint chooses the brand automatically.

voice_idnullable string

Voice, or null for the automatic voice. Missing if the template does not set it.

narration_modeenum

How the text is spoken. Missing if the template does not set it.

Possible values verbatim smooth free
tempoenum

Pace of the film. Missing if the template does not set it.

Possible values presenting lively kinetic
freedomenum

Creative freedom in percent. Missing if the template does not set it.

Possible values 0 25 40 65 100
video_shareenum

Share of moving video clips in percent. Missing if the template does not set it.

Possible values 0 25 50 75 100
target_duration_sinteger

Target duration in seconds (in steps of 6 seconds). Templates in mint allow up to 60 minutes; POST /films accepts at most 900 seconds in settings. Missing if the template does not set it.

Minimum 1
updated_atstring (date-time)

Last change of the template (UTC).

has_moreboolean
next_cursornullable string

Pass as cursor to get the next page; null on the last page.

Errors 400 · 401 · 403 · 404 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/templates
curl "https://api.cream-ai.de/api/v1/templates" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "template",
      "id": "tpl_51",
      "key": "lesson-standard",
      "name": "Lesson – standard",
      "language": "de",
      "settings": {
        "format": "16x9",
        "style_id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
        "brand_id": "brand-northwind-x7k2p9",
        "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
        "narration_mode": "verbatim",
        "tempo": "presenting",
        "freedom": 40,
        "video_share": 25,
        "target_duration_s": 180
      },
      "updated_at": "2026-10-30T16:20:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Styles define the visual look of a film. The API lists the styles your company may use in their approved revision: its own styles, styles shared with it and global styles. Use the id as settings.style_id in POST /films.

Endpoints

Attributes

objectstring
Always style
idstring

Style id in mint.

slugstring
namestring
visibilityenum

organization: style of a company; global: style available to all companies.

accessenum

own: style of this company; shared: style of another company shared with this one; global: global style.

approved_revisioninteger

Approved revision of the style.

Minimum 1
approved_atnullable string (date-time)

Time of the approval (UTC); null if unknown.

updated_atstring (date-time)

Last change of the style (UTC).

The style object
{
  "object": "style",
  "id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
  "slug": "lecture-clean",
  "name": "Lecture – clean",
  "visibility": "organization",
  "access": "own",
  "approved_revision": 4,
  "approved_at": "2026-10-29T09:45:12Z",
  "updated_at": "2026-10-29T09:45:12Z"
}

List approved styles

GET/api/v1/styles
View as Markdown

Approved editorial styles the company can use for films: its own styles, styles shared with it and global styles, each in its approved revision. Sorted by updated_at (newest first), then id. Changes made in mint may take up to 30 seconds to appear.

Query parameters

limitinteger

Page size (1–100).

Default 50 · 1–100
cursorstring

Opaque cursor from next_cursor of the previous page.

Up to 2,048 characters

Returns

200

One page of the list.

Show response attributes
objectstring
Always list
dataarray of style objects
Show child attributes
objectstring
Always style
idstring

Style id in mint.

slugstring
namestring
visibilityenum

organization: style of a company; global: style available to all companies.

accessenum

own: style of this company; shared: style of another company shared with this one; global: global style.

approved_revisioninteger

Approved revision of the style.

Minimum 1
approved_atnullable string (date-time)

Time of the approval (UTC); null if unknown.

updated_atstring (date-time)

Last change of the style (UTC).

has_moreboolean
next_cursornullable string

Pass as cursor to get the next page; null on the last page.

Errors 400 · 401 · 403 · 404 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

404

Not found (not_found).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/styles
curl "https://api.cream-ai.de/api/v1/styles" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "style",
      "id": "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45",
      "slug": "lecture-clean",
      "name": "Lecture – clean",
      "visibility": "organization",
      "access": "own",
      "approved_revision": 4,
      "approved_at": "2026-10-29T09:45:12Z",
      "updated_at": "2026-10-29T09:45:12Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Brands hold the corporate design of your company: styles, voices and more. Use the id as settings.brand_id in POST /films.

Endpoints

Attributes

objectstring
Always brand
idstring

Brand id in mint.

slugstring
namestring
descriptionstring
statusenum
Possible values active draft
style_idsarray of strings

Ids of the editorial styles linked to this brand. Use GET /styles for the styles that are approved.

voicesarray of objects
Show child attributes
voice_idstring

Voice id at the voice provider.

namestring
languagestring

Language code, e.g. de.

defaultboolean

Default voice of the brand for this language.

created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

The brand object
{
  "object": "brand",
  "id": "brand-northwind-x7k2p9",
  "slug": "northwind",
  "name": "Northwind University",
  "description": "Corporate design for all course films.",
  "status": "active",
  "style_ids": [
    "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45"
  ],
  "voices": [
    {
      "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
      "name": "Clara",
      "language": "de",
      "default": true
    }
  ],
  "created_at": "2026-09-14T10:02:44Z",
  "updated_at": "2026-10-21T12:52:17Z"
}

List brands

GET/api/v1/brands
View as Markdown

Brands of the company with their linked styles and voices (no asset URLs). Sorted by name, then id. Changes made in mint may take up to 30 seconds to appear.

Query parameters

limitinteger

Page size (1–100).

Default 50 · 1–100
cursorstring

Opaque cursor from next_cursor of the previous page.

Up to 2,048 characters

Returns

200

One page of the list.

Show response attributes
objectstring
Always list
dataarray of brand objects
Show child attributes
objectstring
Always brand
idstring

Brand id in mint.

slugstring
namestring
descriptionstring
statusenum
Possible values active draft
style_idsarray of strings

Ids of the editorial styles linked to this brand. Use GET /styles for the styles that are approved.

voicesarray of objects
Show child attributes
voice_idstring

Voice id at the voice provider.

namestring
languagestring

Language code, e.g. de.

defaultboolean

Default voice of the brand for this language.

created_atstring (date-time)

Creation time (UTC).

updated_atstring (date-time)

Last change (UTC).

has_moreboolean
next_cursornullable string

Pass as cursor to get the next page; null on the last page.

Errors 400 · 401 · 403 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/brands
curl "https://api.cream-ai.de/api/v1/brands" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "brand",
      "id": "brand-northwind-x7k2p9",
      "slug": "northwind",
      "name": "Northwind University",
      "description": "Corporate design for all course films.",
      "status": "active",
      "style_ids": [
        "b6ed57e1-2c4f-4b8a-9d3e-6f1a0c2b7e45"
      ],
      "voices": [
        {
          "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
          "name": "Clara",
          "language": "de",
          "default": true
        }
      ],
      "created_at": "2026-09-14T10:02:44Z",
      "updated_at": "2026-10-21T12:52:17Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Voices speak the narration. Use the id as settings.voice_id in POST /films, or leave it to the template.

Endpoints

Attributes

objectstring
Always voice
idstring

Voice id at the voice provider. The same voice appears once per language.

namestring
languagestring

Language code, e.g. de.

providerenum
Possible values elevenlabs
brandsarray of objects

Brands that use this voice for this language, sorted by brand_id.

Show child attributes
brand_idstring
defaultboolean

Default voice of this brand for this language.

The voice object
{
  "object": "voice",
  "id": "Xb7hH8MSUJpSbSDYk0k2",
  "name": "Clara",
  "language": "de",
  "provider": "elevenlabs",
  "brands": [
    {
      "brand_id": "brand-northwind-x7k2p9",
      "default": true
    }
  ]
}

List voices

GET/api/v1/voices
View as Markdown

Voices of all brands of the company, one entry per voice and language. Sorted by name, then id. Changes made in mint may take up to 30 seconds to appear.

Query parameters

limitinteger

Page size (1–100).

Default 50 · 1–100
cursorstring

Opaque cursor from next_cursor of the previous page.

Up to 2,048 characters
languagestring

Only voices of this language (language code, e.g. de).

brand_idstring

Only voices of this brand (id from GET /brands).

1–200 characters

Returns

200

One page of the list.

Show response attributes
objectstring
Always list
dataarray of voice objects
Show child attributes
objectstring
Always voice
idstring

Voice id at the voice provider. The same voice appears once per language.

namestring
languagestring

Language code, e.g. de.

providerenum
Possible values elevenlabs
brandsarray of objects

Brands that use this voice for this language, sorted by brand_id.

Show child attributes
brand_idstring
defaultboolean

Default voice of this brand for this language.

has_moreboolean
next_cursornullable string

Pass as cursor to get the next page; null on the last page.

Errors 400 · 401 · 403 · 429 · 500 · 503
400

Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).

401

Missing, malformed, revoked or expired API key (unauthorized).

403

Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).

429

Too many requests (rate_limited).

500

Internal error (internal). Quote the request id when you contact support.

503

Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

GET /v1/voices
curl "https://api.cream-ai.de/api/v1/voices?language=de" \
  -H "Authorization: Bearer $MINT_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "voice",
      "id": "Xb7hH8MSUJpSbSDYk0k2",
      "name": "Clara",
      "language": "de",
      "provider": "elevenlabs",
      "brands": [
        {
          "brand_id": "brand-northwind-x7k2p9",
          "default": true
        }
      ]
    }
  ],
  "has_more": false,
  "next_cursor": null
}