Skip to content

templates.update

Change a saved template

PUT/templates/{id}

Operation
templates.update
MCP tool
templates_update

Change a template's name, description or settings. Every field is optional and an absent one is left alone; settings is replaced WHOLE when it is sent, not merged, so a partial settings object silently drops what it leaves out. A template belonging to another account is 404.

curl 'https://api.gogoscreen.com/api/v1/templates/3f2b0c1a-9d4e-4a61-b8c2-000000000012' \
  -X PUT \
  -H "Authorization: Bearer $GOGOSCREEN_API_KEY" \
  -H "Idempotency-Key: templates-update-mubixu8b" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Product tour, portrait",
  "description": "Phone view, 60 seconds, English, brand voice."
}'
A request to this operation.
json
{
  "template": {
    "id": "3f2b0c1a-9d4e-4a61-b8c2-000000000012",
    "name": "Product tour, portrait",
    "description": "Phone view, 60 seconds, English, brand voice.",
    "isDefault": false,
    "custom": true,
    "limits": {
      "editor": {},
      "executor": {},
      "render": {}
    },
    "voiceId": null,
    "lengthPreset": null,
    "orientationId": null,
    "captureId": null,
    "language": null,
    "background": null,
    "ttsSpeed": null,
    "sourceRenderId": null,
    "updatedAt": "2026-09-21T11:18:00.000Z"
  }
}
200 response, captured from a real call. Ids, timestamps and signed URLs are replaced; the shape is untouched.

At a glance

FactDetail
Scopesrenders:write
Credentialsa signed in dashboard session or an API key.
Rate limit120 requests a minute per credential, in the write class.
IdempotencyRequired. Send an Idempotency-Key header; a retry with the same key and the same body returns the stored answer with Idempotent-Replayed: true. How idempotency works.
MCP tooltemplates_update
Always setsCache-Control: private, no-store

Path parameters

NameTypeRequiredDescription
idstringRequiredThe template's id — the id a create call answered with, or one from templates.list. A template id is not a uuid.1–64 characters

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.

NameTypeRequiredDescription
descriptionstringOptionalmax 300 characters
namestringOptional1–80 characters
settingsobjectOptionalThe render settings this template pins: limits, voice, length preset, orientation, capture, language, background, voice speed. Open shape, may gain keys; ≤65536 bytes, ≤16 deep.any keys

Response

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

200 OK

Change a saved template

200 OK body
NameTypeDescription
templateobject
17 fields inside template
NameTypeDescription
backgroundstring | null
captureIdstring | null
custombooleantrue for one of this account's saved templates, false for a system template.
descriptionstring
idstring
isDefaultboolean
languagestring | null
lengthPresetstring | null
limitsobject | nullThe engine limits this template pins. Open shape, may gain keys; ≤65536 bytes, ≤16 deep.any keys
namestring
orientationIdstring | null
sourceRenderIdstring | null
speedFactornumber | nullSystem templates only: a factor on the voice's own speed.
ttsSpeednumber | null
updatedAtstring | nullformat: date-time
voiceIdstring | null
voiceStylestring | nullSystem templates only: the delivery the narrator reads in.
200 OK headers
HeaderMeaning
Cache-ControlAlways private, no-store.
Idempotent-ReplayedPresent only when this answer was stored by an earlier call with the same Idempotency-Key. Nothing new was done.

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
description_invalid400A saved template's description is longer than allowed.Keep it to 300 characters or fewer.
idempotency_key_required400A mutating operation arrived over HTTP with no Idempotency-Key header. It is refused before the body is parsed, so a caller missing both learns about both at once.Add an Idempotency-Key header of up to 128 characters, unique to this request. Over MCP the same value goes in the idempotencyKey tool argument.
length_below_minimum400The 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.
name_invalid400A saved template's name is empty or longer than 80 characters.Send a name between 1 and 80 characters.
orientation_unknown400The orientation named is not in the catalogue.Read GET /catalog/render-options and send an id from orientations.
settings_invalid400The settings object on a saved template is not valid.Send only keys the template settings schema declares, with values the catalogue offers.
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.
voice_unknown400The voiceId named is not in the catalogue.Read GET /catalog/voices and send an id it lists.
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.
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.
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.
source_render_not_found404The sourceRenderId or renderId named is not a render of this account.Send a render id this account owns. A render belonging to somebody else answers the same way.
template_not_found404No saved template of that id belongs to this account.Check the id, or list the account's templates.
conflict409The request conflicts with the state the resource is in, and no more specific code applies.Re-read the resource and decide from its current state. Retrying the same request unchanged will not help.
idempotency_conflict409That idempotency key has already been used on this operation with a different request body.Use a fresh key for a different request. A key stands for one intent, not for one attempt.
idempotency_in_progress409The first request under that key is still being worked. Two concurrent identical requests both reach the store and one of them is told this.Wait the Retry-After seconds, which is 2, and send exactly the same request again with the same key. Do not change the body and do not mint a new key.
template_limit409The account already holds the most saved render templates it may.Delete one, then save the new one.
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.
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.