# Restore a previous version of a topic

`POST /v1/topics/{name}/versions/{version}/restore`

- Authentication: required (Bearer token)
- Required scope: `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.

## Example request

```bash
curl -X POST 'https://api.sendops.dev/v1/topics/string/versions/0/restore' \
  -H "Authorization: Bearer $SENDOPS_API_KEY"
```

## Responses

### 200 — The definition after the restore, and the version the restore created

Content type: `application/json`

```json
{
  "kind": "string",
  "restored": 0,
  "current": {
    "name": "string",
    "display_name": "string",
    "description": "string",
    "default_subscription_status": "OPT_IN",
    "subscriber_count": 0,
    "status": "active",
    "created_at": "2026-05-17T20:00:00Z",
    "updated_at": "2026-05-17T20:00:00Z"
  },
  "version": {
    "version_number": 0,
    "created_at": "2026-05-17T20:00:00Z",
    "actor": {
      "kind": "user",
      "id": "string",
      "label": "string",
      "session": "string"
    },
    "content_hash": "string",
    "summary": "string"
  }
}
```

### 401 — Missing, malformed, or unknown API key

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```

### 403 — Key lacks the required scope or plan limit violated

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```

### 404 — Resource not found

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```

### 429 — Per-org rate limit exceeded

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```

### 500 — Unexpected server-side failure. The `code` is `internal_error`. The
`request_id` field can be quoted to SendOps support to investigate.

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```
