renders.quote
What a render would cost
POST/renders/quote
How many seconds a render of these OPTIONS would reserve, whether it would carry the free-tier watermark, and what the account has available — creating nothing and spending nothing. It prices the options only: there is no url field and the address does not change the price, so this is not the tool that records anything. A POST because the options are a body, not a query string; it is a read, safe to call as often as you like.
curl 'https://api.gogoscreen.com/api/v1/renders/quote' \
-X POST \
-H "Authorization: Bearer $GOGOSCREEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"targetSeconds": 60
}'{
"secondsToReserve": 60,
"watermark": false,
"capped": false,
"targetSeconds": 60,
"maxSeconds": null,
"sufficient": true,
"needed": null,
"availableSeconds": 542
}At a glance
| Fact | Detail |
|---|---|
| Scopes | renders:read |
| Credentials | a signed in dashboard session or an API key. |
| Rate limit | 600 requests a minute per credential, in the read class. |
| Idempotency | Not applicable. This operation changes nothing. |
| MCP tool | renders_quote |
| Always sets | Cache-Control: private, no-store |
Request body
A JSON body is optional. Unknown fields are refused rather than ignored, so a typo is a 400 validation_failed rather than a setting that silently did nothing.
| Name | Type | Required | Description |
|---|---|---|---|
| background | string | Optional | max 64 characters |
| captionStyle | string | Optional | max 64 characters |
| capture | string | Optional | max 64 characters |
| language | string | Optional | max 16 characters |
| maxSeconds | integer | Optional | The ceiling an Auto render may grow to, 1–600 seconds.1–600 |
| orientation | string | Optional | max 64 characters |
| targetSeconds | integer | Optional | A fixed length, 1–600 seconds. Omit for Auto, which sizes itself and is capped by maxSeconds.1–600 |
| templateId | string | Optional | max 64 characters |
| voiceId | string | Optional | max 64 characters |
200 OK
What a render would cost
| Name | Type | Description |
|---|---|---|
| availableSeconds | number | |
| capped | boolean | True when the length asked for was reduced to fit the balance or the free-tier ceiling. |
| maxSeconds | number | null | |
| needed | number | null | |
| secondsToReserve | number | What renders.create would hold. Zero means nothing would be held (the free tier). |
| sufficient | boolean | False when the balance would refuse the render; needed says what it would take. |
| targetSeconds | number | null | |
| watermark | boolean | Whether the video would carry the free-tier mark. |
| Header | Meaning |
|---|---|
Cache-Control | Always private, no-store. |
Errors
Every refusal is { error: { code, message, details?, requestId } }. Branch on code, never on the sentence. The full catalogue is at Errors.
| Code | Status | When it happens | What to do |
|---|---|---|---|
| avatar_unavailable | 400 | A presenter circle was asked for on a deployment where the presenter is switched off. | Make the video without one. While the presenter is off, avatarId is not declared on the public schemas at all, so a public caller meets validation_failed first. |
| avatar_unknown | 400 | The avatarId named is not in the catalogue. | Read GET /catalog/render-options and send an id from avatars. |
| background_unknown | 400 | The background named is not in the catalogue. | Read GET /catalog/render-options and send an id from backgrounds, or omit the field for the default. |
| caption_style_unknown | 400 | The captionStyle named is not in the catalogue. | Read GET /catalog/render-options and send an id from captionStyles. |
| capture_incompatible | 400 | A phone view capture was paired with a landscape orientation. Phone view only makes a portrait video. | Pick a portrait orientation, or switch the capture to a computer window. |
| capture_unknown | 400 | The capture named is not in the catalogue. | Read GET /catalog/render-options and send an id from captures. |
| language_unknown | 400 | The language named is not in the catalogue. | Read GET /catalog/render-options and send a code from languages. |
| length_below_minimum | 400 | The length asked for is shorter than a walkthrough can be. The floor is 30 seconds. | Ask for at least 30 seconds, or omit targetSeconds for Auto, which sizes itself. |
| options_invalid | 400 | The render options do not resolve together, for a reason the per field codes do not cover. | Re-read GET /catalog/render-options and send a combination it offers. renders.quote prices options without creating anything. |
| orientation_unknown | 400 | The orientation named is not in the catalogue. | Read GET /catalog/render-options and send an id from orientations. |
| template_unknown | 400 | The templateId named is neither a system template nor one of this account's saved templates. | Read GET /catalog/render-options and send an id it lists, or a saved template id from GET /templates. |
| validation_failed | 400 | The merged path, query and body did not match the operation's schema. The schemas are strict, so an unknown field is a failure rather than something ignored, and a string carrying half of a character is refused before it can be stored. | Read details.issues. Each entry carries a path, a message and a machine readable code. Fix every named field and send the request again; the same body always fails the same way. |
| voice_language | 400 | The voice chosen does not speak the language chosen. | Read GET /catalog/voices and pick a voice listed for that language, or change the language. |
| voice_unknown | 400 | The voiceId named is not in the catalogue. | Read GET /catalog/voices and send an id it lists. |
| unauthorized | 401 | No credential was presented, or the key is unknown, revoked or expired, or an X-API-Key header carried something that is not an API key. details.reason says which. | Send Authorization: Bearer gsk_live_…. A revoked or expired key never starts working again, so issue a new one in the developer console. Put a dashboard session token in Authorization, never in X-API-Key. |
| forbidden_scope | 403 | The credential does not carry every scope the operation declares, or it is the wrong kind of credential for it. keys.* and assistant.* are user only and can never be called by a key. | details.requiredScopes and details.missingScopes name what is missing. A key's scopes cannot be changed after it is issued, so create a new key with them. When details.allowedActors is present, no key can call this operation at all. |
| not_found | 404 | No resource of that id belongs to this account. A resource that belongs to somebody else answers 404 as well, never 403. | Check the id. Do not treat this as a permissions problem. |
| payload_too_large | 413 | The request body is over the transport's limit: 256 kb over HTTP, 1 mb over MCP. | Send less. details.limit carries the limit. Version 1 has no upload operations, so a body this size is usually a mistake. |
| unsupported_media_type | 415 | The request carried a body whose Content-Type is not application/json, whose charset is not utf-8, or whose Content-Encoding this API does not decode. A body nobody can read would otherwise be silently discarded. | Send Content-Type: application/json and utf-8 bytes. details names the charset, encoding or content type that was objected to. |
| rate_limited | 429 | The credential's per minute budget, the account's per minute ceiling, or a daily cap was exceeded. details.scope is minute, day or account, or global when the product's own daily cap on voice previews is spent. | Wait the Retry-After seconds and retry. details.limit and details.resetAt say what was hit and when it reopens. The RateLimit-* headers on every answer let a client pace itself before it gets here. |
| internal_error | 500 | An unhandled failure inside this API. The original message is logged and never answered. | Retry once, then quote requestId to support. A 5xx deletes the idempotency claim rather than storing it, so retrying under the same key is safe. |