/pingCheck that the key is valid. No fields.
response
- ok: true
API v1
Version 1 (v1), additive only: new endpoints and optional fields are added; nothing existing is removed or changed.
We never delete videos, but we recommend downloading each finished video once and hosting it on your own server. Prices and your wallet are the same as on mystage.film.
From a category to a video on your own server. Every POST sends a new Idempotency-Key. Full guide as text: docs/api/guides/quickstart.md, also served at /llms.txt.
poster_url, video_url, example_poster_url and example_video_url are on our media CDN, which answers 403 to a request without a Referer header. In a browser do not use Referrer-Policy no-referrer (strict-origin or the default works). A server that downloads media must send a Referer, any https origin such as your own site. Hotlinking our CDN is not supported for production sites: download the poster and the video once and serve them from your own storage or CDN. The finished video link (GET /v1/orders/{id}/video) needs no Referer but expires at expires_at.
A short, exact guide for agents: the call order, the required headers, the money rules (always show the price and get the human's confirmation before POST /v1/orders), how to fill intake forms from the schema, polling intervals and the media Referer rule. The OpenAPI document is public at /api/v1/openapi.json.
Open /llms.txtEvery call sends your API key in the Authorization header, Bearer style. No cookies, no CORS: the API is called from your backend, not the end user's browser. The key can ONLY reach your own account: every order, file and money movement is bound to your account, whatever you send. The key is shown once at creation; if it leaks, revoke it from the portal and make a new one.
Authorization: Bearer vapi_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
All endpoints live under https://mystage.film/api/v1. Responses are JSON. Every response carries an x-request-id header: quote it when contacting support.
https://mystage.film/api/v1
List endpoints return { data, has_more, next_cursor }. Pass next_cursor as the cursor query parameter on the next call. limit: 1 to 100 (default 20). Orders and usage are newest first; videos are in catalog order. With filters a page can hold fewer items while has_more is true.
Every POST that creates something (orders, uploads, change requests, approvals, cancel) REQUIRES the Idempotency-Key header with a unique value per operation (for example one UUID per operation). Same key and same body: the stored answer, never a second run. Same key and a different body: 422 idempotency_mismatch. A key still running: 409 idempotency_in_flight. Responses are kept for 48 hours; server errors (5xx) are not stored. A network retry can therefore never create a duplicate order or a double charge. A stored 402 replays too: after a top up, use a new key.
Idempotency-Key: 8f3c1d2a-77b9-4c1e-9a01-5f6e8d9c0b1a
All errors follow RFC 9457 (application/problem+json) with type, title, status, code, request_id and, for field problems, an errors list. Branch on code. The codes you will meet and what to do:
Up to 120 calls per minute per key (reads and writes together) and up to 30 POST/PATCH/DELETE per minute per key. A 429 answer carries Retry-After. Refused calls are never charged.
Instead of polling GET /v1/orders, register a webhook and we notify you when one of your orders changes: order.created, order.paid, order.production_started, order.storyboard_ready, order.awaiting_approval, order.changes_requested, order.delivered, order.failed, order.cancelled. You only receive events for your own orders, never for other accounts. The body carries ids and status only: read the details with GET /v1/orders/order_id.
Every request follows Standard Webhooks: headers webhook-id, webhook-timestamp and webhook-signature, signed with the endpoint secret. Check the signature before you trust an event. If the endpoint does not answer 2xx we retry for about 27 hours; after 5 days of continuous failures we disable it.
All calls are relative to the base URL. Bodies are strict: unknown fields are refused.
/pingCheck that the key is valid. No fields.
/meYour key, your account, your wallet balance and a 30 day usage summary (calls, orders, charges in cents).
curl -H "Authorization: Bearer $KEY" https://mystage.film/api/v1/me
/usageThe key's request history: route, method, status, order_id when the call created an order, and credits_cents for what it debited. Cursor pagination.
curl -H "Authorization: Bearer $KEY" "https://mystage.film/api/v1/usage?limit=50"
/video-categoriesThe categories of the showcase, with their slug, English and Greek name and how many videos each has.
curl -H "Authorization: Bearer $KEY" https://mystage.film/api/v1/video-categories
/videosThe showcase videos, all or one category. Each item has poster_url, video_url (HLS), duration_seconds, categories (names), category_slugs and product_id: the product that orders a video like this one, or null for an example only. Filters: category, tag, q, aspect. Media needs a Referer header.
curl -H "Authorization: Bearer $KEY" "https://mystage.film/api/v1/videos?category=restaurants&limit=20"
/videos/{videoId}One showcase video, the same shape as a list item. 404 not_found for an unknown id.
/model-libraryReady made AI models to answer a model-picker field (the model id) or a person-spec field in library mode. Filter: gender.
/model-library/{modelId}One library model with its front, back, side and portrait images.
/productsYour catalog: title (EN, EL), subtitle, prices per length, duration_prices, aspect_ratios, has_storyboard, categories, tags, an example video and poster. Filters: category, tag, q, aspect, length_seconds. Cursor pagination.
curl -H "Authorization: Bearer $KEY" "https://mystage.film/api/v1/products?category=restaurants"
/products/{productId}One product by id or slug, all details. has_storyboard true means the order stops once for a storyboard the customer approves; false means it goes straight to the finished video.
/products/{productId}/intake-formThe answer fields the product asks for: type, label, required, options, show_if, upload slots, model_library and api_settable. Build your form from here; leave out hidden fields and fields with api_settable false (the default applies).
/uploadsIdempotency-Key requiredRequests a presigned URL for one intake file. Body: purpose "intake", content_type (image/jpeg, image/png, image/webp, audio/mpeg, audio/mp4), size_bytes (up to 50 MB, exact). PUT to url with exactly the returned headers before it expires (10 minutes). Keep the upload_id for the order answers.
curl -X POST -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $IDEM" \
-H "Content-Type: application/json" -d '{"customer_id":"…","purpose":"intake","content_type":"image/jpeg","size_bytes":48123}' \
https://mystage.film/api/v1/uploads
curl -X PUT -H "content-type: image/jpeg" --data-binary @photo.jpg "$UPLOAD_URL"/ordersIdempotency-Key requiredCreates the order and charges your wallet in one transaction. Body: customer_id, product_id, length_seconds (from the prices), aspect (optional, from aspect_ratios), add_ons { subtitles, extra_formats, resolution, duration_seconds } (optional, only what the product offers), answers (the intake form fields; files as upload_id), uploads (list of upload_id), review (optional). complimentary is not available through the API. 402 insufficient_credit when the balance is not enough: nothing is created or charged.
curl -X POST -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $IDEM" \
-H "Content-Type: application/json" -d '{"customer_id":"…","product_id":"…","length_seconds":15,"answers":{},"uploads":[]}' \
https://mystage.film/api/v1/orders/ordersYour orders, newest first. Filters: status, created_after (ISO), customer_id. Cursor pagination.
curl -H "Authorization: Bearer $KEY" "https://mystage.film/api/v1/orders?status=delivered"
/orders/{orderId}One order: status (received, awaiting_approval, changes_requested, in_production, delivered, failed, cancelled, awaiting_balance), details, add ons, total_cents, cancellation_requested.
/orders/{orderId}/cancelIdempotency-Key requiredFiles a cancellation REQUEST for our staff (201, status pending). Body: reason (required, 10 characters or more). Production is not stopped and nothing is refunded automatically: our team decides the request and any refund. The order can still be delivered meanwhile.
/orders/{orderId}/storyboardOnly for products with has_storyboard true: the current storyboard, its version_id, status and scenes with images (links valid 10 minutes). 404 storyboard_not_ready before it is ready.
/orders/{orderId}/storyboard/approveIdempotency-Key requiredApproves the storyboard on behalf of the customer; production continues. Body: version_id from GET storyboard.
/orders/{orderId}/change-requestsIdempotency-Key requiredRequests changes on scenes. Body: version_id and changes, a list of scene_index and comment (10 to 2000 characters). A round may be paid from the wallet (402 revision_payment_failed); 15 second videos can only be approved.
/orders/{orderId}/videoOnly when delivered: a download URL for the finished MP4 and expires_at (10 minutes). Do not store the link, ask again. Download the file once and host it on your own server.
/webhook-endpointsRegisters a webhook for your own orders. Body: url (public https, port 443), events (order.* only), description (optional). The response holds the signing secret, shown only this once. Up to 5 endpoints per account.
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"url":"https://example.com/hooks/in","events":["order.delivered","order.storyboard_ready"]}' \
https://mystage.film/api/v1/webhook-endpoints/webhook-endpointsYour webhook endpoints, newest first. The secret is never shown again.
/webhook-endpoints/{endpointId}One of your webhook endpoints.
/webhook-endpoints/{endpointId}Changes url, events or description, or disables and enables it again (status active or disabled).
/webhook-endpoints/{endpointId}Deletes an endpoint that never received a delivery. If it has delivery history, disable it instead.
/webhook-endpoints/{endpointId}/testSends a signed webhook.ping test event now and reports whether the endpoint answered 2xx.
/webhook-endpoints/{endpointId}/rotate-secretA new signing secret, shown only in this response. Events are signed with it from now on.
Cookies
We use analytics cookies to understand how this site is used. They are not needed for the site to work, and your choice changes nothing about the service you receive. Read our Privacy Policy