Skip to content

marketing.generations.preflight

Would this generation be accepted?

POST/marketing/generations/preflight

Operation
marketing.generations.preflight
MCP tool
marketing_generations_preflight

Judge a generation request without starting one: the design exists, the manifest has the pictures it needs, the words would fit the frames, the brand is resolvable. Allocates nothing, spends nothing, creates nothing — it is a read in every sense but the verb, which is a POST because the request is a body. A refusal names the field, so a form can point at it before a customer waits for a video.

curl -X POST "https://api.gogoscreen.com/api/v1/marketing/generations/preflight" \
  -H "Authorization: Bearer $GOGOSCREEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "durationSeconds": 7, "format": "portrait", "source": { "kind": "website", "sourceId": "<sourceId>", "version": 1 }, "templateId": "<templateId>" }'
A request to this operation.

At a glance

FactDetail
Scopesmarketing:write
Credentialsa signed in dashboard session or an API key.
Rate limit20 requests a minute per credential, in the expensive class.
IdempotencyNot applicable. This operation changes nothing.
MCP toolmarketing_generations_preflight
Always setsCache-Control: private, no-store
Verified emailRequired. An account whose email address is not verified meets 403 email_unverified before the operation runs.
Marketing videosRequired. An account without marketing videos enabled meets 403 feature_disabled before the operation runs.

Request body

A JSON body is required. Unknown fields are refused rather than ignored, so a typo is a 400 validation_failed rather than a setting that silently did nothing.

NameTypeRequiredDescription
durationSecondsintegerRequiredOne the design offers at this format, from catalog.marketing.templates.list. The six-second edition is retired and is refused here.7–600
formatstringRequiredone of: portrait, landscape, square, four-five
sourceobjectRequiredWhich scanned website and which manifest version this is made from.
kindstringRequiredAlways website. The only source kind this field takes.always "website"
manifestHashstringOptionalThe manifest's sha256, as marketing.sources.get answers it. Pins the exact scan this was planned against.pattern: ^[a-f0-9]{64}$
sourceIdstringRequiredThe id of a scanned source from marketing.sources.list.format: uuid
versionintegerRequiredWhich manifest version of that source — marketing.sources.get answers the current one.1–100000
templateIdstringRequiredA design id from catalog.marketing.templates.list (family=website).1–64 characters
assetUseConsentbooleanOptionalYour consent to use the pictures the scan found on your own site.always true
assistbooleanOptionalHave the words written for you. Requires assetUseConsent.always true
audioModestringOptionalone of: music, silent, voice, voice-music
brandChoicestringOptionalone of: saved, website
brandNamestringOptional1–40 characters
briefobjectOptional{ audience, objective, mustSay } — what the words should aim at.any keys
expectedRevisionIdstringOptionalformat: uuid
musicobjectOptional{ trackId } from the design's own catalogue.any keys
narrationobject | nullOptionalThe voice the words are written FOR: { voiceId, language, cadence, synthesisSpeed? }. Absent means no spoken narration.any keys
projectIdstringOptionalRe-generate INTO an existing project; requires expectedRevisionId.format: uuid
reviewobjectOptionalThe approved copy and scene choices. Judged by the campaign contract's own schema.any keys
templateVersionstringOptionalmax 16 characters
titlestringOptional1–200 characters

Response

Answers 200. Every answer also carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset, and every error body carries a requestId.

200 OK

Would this generation be accepted?

200 OK body

This response has no body fields.

200 OK headers
HeaderMeaning
Cache-ControlAlways 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.

CodeStatusWhen it happensWhat to do
brand_logo_source_mismatch400The logo choice names a source other than the one the generation is being built from.Choose a logo from the source this generation reads, or use the brand kit's own.
unsupported_duration400The design does not offer that length.details.durations lists what it does offer. Pick one of those.
validation_failed400The 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.
unauthorized401No 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.
insufficient_seconds402The account's seconds wallet does not hold enough time for the video that was asked for. It is the only refusal on this surface that is a 402.details.needed and details.available are the two numbers. Buy more time, or ask for a shorter video. Retrying without changing either fails the same way.
forbidden_scope403The 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.
generation_not_found404No generation of that id belongs to this account.Check the id. A generation belonging to another account answers the same way.
not_found404No 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.
project_not_found404No marketing project of that id belongs to this account.Check the id. A project belonging to another account answers the same way.
source_not_found404No website source of that id belongs to this account.Check the id. A source belonging to another account answers the same way.
source_version_not_found404No such version of that website source.Read the source to see which versions exist, then name one of those.
brand_kit_required409The generation needs a brand kit and the account has never saved one.Save one with PUT /marketing/brand-kit first. name and accent are the two required fields.
brand_logo_not_retained409The generation asked for a logo the account no longer holds, because retention took it.Pick a different logo choice, or scan the source again so a logo is held.
generation_busy409Another generation is already running for this source. One at a time per account.Poll the running one until its state is terminal, or cancel it, then start the new one.
generation_idempotency_conflict409That idempotency key was already used on this account with a different generation request.Use a fresh key for a different request. One key stands for one intent.
generation_not_retryable409A retry was asked for on a failure that a retry cannot change, for example a design that cannot fit the words.Read retryable on the generation before asking. When it is false, fix the request and start a new generation.
source_kind_mismatch409The project was made from a different kind of source than the one being used, for example a walkthrough render where a scanned website is expected.Use the source the project was built from, or start a new project of the right kind.
source_owner_unavailable409The account cannot start new work, because it is blocked or scheduled for deletion.Resolve the account's state, then retry.
source_version_mismatch409The version named belongs to a different website source.Send a version number from the source you are naming.
source_deleted410The website source has been deleted. It still reads state: "cancelled".Scan the site again with marketing.sources.create.
source_expired410The website source is past its retention window.Scan the site again. Projects already built from it keep the version they were built from.
source_version_expired410That manifest version has been cleaned up.Scan the site again and build from the new version.
payload_too_large413The 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_type415The 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.
campaign_copy_overflow422Words sent for a marketing scene do not fit the frame the design draws them in. The fit is measured, not guessed.Shorten the fields details.fields names, then send the revision again. marketing.generations.preflight answers the same refusal before anything is created.
campaign_logo_aspect_unsupported422The logo's aspect ratio is not one any design can place.Supply a logo closer to square or to a standard wordmark shape.
campaign_unsupported_claim422A statement sent for the film is not supported by anything the scanned website says.Reword the claim so it repeats something the source actually says, or drop it.
campaign_visuals_insufficient422The design needs more pictures than the scanned source has.details says how many are needed and which scenes are short. Scan a richer page, refresh the source, or choose a design with fewer picture slots.
invalid_campaign_narration422The narration request for a marketing film is not a valid shape.Send narration as the operation's schema declares it, or omit it and let the design's default stand.
rate_limited429The 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_error500An 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.