Restore a previous version of a topic

Search Documentation

Search across all developer documentation

topics

Restore a previous version of a topic

POST /v1/topics/{name}/versions/{version}/restore
Auth required api.topics.manage

Reinstates a previous definition. A restore is an ordinary edit whose content happens to be old: it snapshots the state it replaces in the same transaction, so nothing is lost, the restore is itself in the history, and restoring the version it created undoes it. That is why this operation is NOT classified destructive, and why a test-environment credential may call it.

It bypasses the optimistic-concurrency check by design — "whatever is there now, make it this" is not a statement about what the caller last read — and it deletes no history.

The restored definition is written through to the organization's SES contact list, so what a subscriber sees follows the restore. Every contact's stored preference for the topic is untouched.

Path parameters

name string required

The topic's org-unique name (its SES key).

version integer required

The version number, as returned by the versions collection. Version numbers are the handle on every kind here, including the kinds whose dashboard routes address a version by row id.

Responses

Errors follow the RFC 7807 problem format — see the error reference.

200 The definition after the restore, and the version the restore created application/json
kind string required
restored integer required

The version number that was reinstated.

current object required

The definition as it now stands, in the shape the kind's own read route returns.

version object required

One row of a definition's history.

Fields of version:

version_number integer required
created_at string<date-time> required

When the snapshot was taken, which is when the edit that REPLACED this state was made — not when this state was authored.

actor object required

Who made one edit. The label is resolved server-side — a person's name, an API key's name, an OAuth client's name — because the name lives in a different table per kind and a client can read none of them. It never carries a key, a token or a client secret; a revoked credential falls back to a short form of its id rather than rendering blank.

Fields of actor:

kind string enum required

unknown is an honest value rather than an error: it is what rows predating actor recording carry, and what a write reached with no credential records.

One of: user, api_key, oauth_client, system, unknown

id string optional

The users / api_keys / oauth_clients id, per kind. Absent for system and unknown.

label string required
session string optional

The HTTP request id of the edit — the same value on the matching audit row, so the two can be joined. It is NOT an MCP session id: the MCP transport is stateless and reads no session header.

content_hash string optional
summary string required

How this version differs from the one before it — +3 −1 lines for a source kind, renamed, type string→number for a schema kind. The oldest row says first recorded version.

current object optional

Fields of current:

name string required

Stable topic identifier used in filters and preferences.

display_name string required
description string required
default_subscription_status string enum required

One of: OPT_IN, OPT_OUT

subscriber_count integer<int64> required

Contacts effectively subscribed to this topic — those whose explicit preference is OPT_IN, plus those with no explicit preference on a topic whose default_subscription_status is OPT_IN. Excludes master-unsubscribed contacts. This is the set that would be mailed.

status string enum required

Lifecycle state. archived never blocks the topic's use.

One of: active, archived

created_at string<date-time> required
updated_at string<date-time> required
401 Missing, malformed, or unknown API key application/problem+json
403 Key lacks the required scope or plan limit violated application/problem+json
404 Resource not found application/problem+json
429 Per-org rate limit exceeded application/problem+json
500 Unexpected server-side failure. The code is internal_error. The request_id field can be quoted to SendOps support to investigate. application/problem+json