Skip to main content
PATCH

Path Parameters

string
required
The template’s UUID. A value that is not a well-formed UUID returns 400 ({"error": "invalid templateId"}) — the format check runs before the lookup. A well-formed UUID that does not belong to one of the account’s organizations returns 404.

Body Parameters

Only author-editable fields are accepted; unknown fields are rejected (400).
string
Max 100 chars, unique within the organization.
string
Max 300 chars.
string
Message body with {{token}} placeholders. Max 5000 characters; longer is rejected with 400.
string[]
Free-form tags. Max 50 tags, each up to 64 characters.
string
Sender identity (phone number, short code, or alphanumeric sender ID) overriding the From Number on the agent’s Send SMS function. A phone number must be an SMS-capable number on the organization’s Twilio account (see Twilio) — verified at agent assignment, not here; an unowned number is rejected at send time with error 21606. Max 64 characters.
string
draft, active, or archived. Activating a template flagged is_first_contact requires opt-out language in the body (e.g. “Reply STOP to opt out”), else 400.Moving a template off active breaks every agent already bound to it. Archiving — or returning it to draft — only hides it from selection; existing bindings are left in place, and from the next call those agents’ Send SMS fails with template_not_found instead of sending. The API does not warn you, and unlike DELETE — which is refused while any agent references the template — this is not blocked. Re-point the bound agents first.
boolean
Whether this may be the first SMS to a recipient.
string[]
ISO 3166-1 alpha-2 country codes (e.g. ["US","CA"]). Case-insensitive — values are upper-cased before storage, so ["us"] and ["US"] are equivalent. UK and EL are accepted as aliases for GB and GR. A code that is not ISO 3166-1 alpha-2 is rejected with 400: it would match no recipient and silently block every send from the template. Max 300 entries.
string
MMS media URL (max 2048 chars); may contain {{token}} placeholders resolved at send time. The uploaded media object itself (media_key) is server-managed and cannot be set here.
object
Token → sample-value map (max 100 keys, values max 1000 chars) used to preview the rendered message.
integer
Optional optimistic-concurrency guard. Pass the version you read from the template; if it has changed since, the update is refused with 409 instead of overwriting whatever landed in between. Omit it to update unconditionally (last write wins).This is a guard, not a field — it is never written. The stored version is always incremented by the server.
For an unknown or immutable field the offending key appears in message, not in path — path is empty, because the rejection belongs to the object rather than to one of its properties. Error handling that matches on issues[].path will not catch these. For a field that exists but holds a bad value (e.g. name over 100 characters), path is the field name as you would expect.

Concurrency

Read-modify-write against this endpoint is last-write-wins by default: two callers that both GET a template and then PATCH it will each succeed, and the first one’s changes are lost with no error. To avoid that, send the version you read as expected_version. A mismatch returns 409 version_conflict and nothing is written — re-read the template, reapply your change, and retry.
cURL
A 409 is also returned when the new name collides with another template in the same organization — distinguishable by error, which is version_conflict for a concurrency clash and carries the duplicate-name message otherwise. Omitting expected_version narrows but does not eliminate the risk: the write is still guarded against anything landing between this request’s own read and its update. That window is very small, and it returns the same 409 version_conflict, so a caller need only handle one case.

Availability

Returns 403 when SMS Template Manager is locked for the template’s organization — except an archive-only patch, which is never blocked. Archiving stays available even when the feature is otherwise locked, so a locked organization can always tidy up. An archive-only patch is one whose only content change is {"status": "archived"}. expected_version may accompany it and still counts as archive-only, since it is a concurrency guard rather than a field being written: