# Undelete a sealed record

Restores a deleted record with the content it had when it was deleted, as a new revision. The answer is the envelope; [read the record](/docs/api-reference/sealed-stores/get-record) for the restored content. To see what a tombstone held before deciding, read its [revision history](/docs/api-reference/sealed-stores/list-revisions).

The body names the tombstone's revision. A live record is `409 SEALED_RECORD_NOT_DELETED` and a stale revision `409 SEALED_RECORD_REVISION_CONFLICT`, both with the record in `error.details.current`. An undelete is refused like a create when the kind's live-record cap is full: `422 SEALED_RECORD_LIMIT_REACHED`, or for `favourites` `409 SEALED_RECORD_SINGLETON_EXISTS` with the live one. A tombstone past its 30 days is gone: `404 SEALED_RECORD_NOT_FOUND`.

Requires an `Idempotency-Key` header: re-sending the same key answers the first call's exact response (header `Idempotent-Replayed: true`) and changes nothing; a refused call is not remembered, so it may be retried with the same key.

#### Path Parameters

**`store`** string required

The store: `aitronos-browser`. Up to 64 characters; an unknown store is `404 SEALED_STORE_NOT_FOUND`.

**`record_id`** string required

The record's id, as the client minted it: 16 to 128 characters of `A-Z a-z 0-9 _ -`.

#### Headers

**`Authorization`** string required

`Bearer <access token>` from the person's own sign-in. API keys and service accounts are refused with `403 SEALED_STORE_PERSONAL_SESSION_REQUIRED`.

**`Idempotency-Key`** string required

A random id minted once for this change and sent again on every retry of it: 16 to 128 printable ASCII characters, no spaces (a UUID works). The first accepted answer is remembered for 30 days; see [Idempotency-Key](/docs/api-reference/sealed-stores/introduction#idempotency-key).

#### Body Parameters

**`revision`** integer required

The tombstone's revision, as the [deleted list](/docs/api-reference/sealed-stores/list-deleted), the feed or a read returned it. At least 1.

**`device_id`** string required

The undeleting device's id: the device id it signed in with. 16 to 255 characters of `A-Z a-z 0-9 . _ : @ -`.

## Returns

`200 OK` with the record's envelope at its new revision: `deleted` is `false` and `payload_bytes` is the restored content's size.

- **`object`** string — `sealed_record_envelope`.
- **`id`** string — the client's record id.
- **`kind`** string — `session` or `favourites`.
- **`schema_version`** integer — as the last accepted write sent it.
- **`revision`** integer — server-assigned; rises by 1 on every accepted write.
- **`created_at`** string — when the record was created (ISO 8601 UTC).
- **`last_touched_at`** string — set by the server on every accepted write. Sort by it, ties by `id`.
- **`deleted`** boolean — whether the record is a tombstone.
- **`deleted_at`** string or null — when it was deleted.
- **`device_id`** string — the device of the last accepted write.
- **`payload_bytes`** integer or null — the decoded payload size; `null` for a tombstone.


There is no copy of the sealed content: [get the record](/docs/api-reference/sealed-stores/get-record) or read the [change feed](/docs/api-reference/sealed-stores/list-changes) for it.

Every answer carries the header **`Idempotent-Replayed`**: `false` on the first answer, `true` when this is the remembered answer to an `Idempotency-Key` sent before.

## Errors

| Status | Code | When |
|  --- | --- | --- |
| 401 | `AUTHENTICATION_REQUIRED` | No access token, or one that is not valid. |
| 403 | `SEALED_STORE_PERSONAL_SESSION_REQUIRED` | The call used an API key or a service account. Only a person's own sign-in session reaches a sealed store. |
| 404 | `SEALED_STORE_NOT_FOUND` | No store with that name (`details.store`). |
| 404 | `SEALED_RECORD_NOT_FOUND` | No record with that id in the caller's store, or its tombstone has passed the 30-day retention. |
| 409 | `SEALED_OPERATION_IN_PROGRESS` | An earlier call with this `Idempotency-Key` has not finished. Retry in a moment. |
| 409 | `SEALED_RECORD_NOT_DELETED` | The record is live. `details.current` is the record. |
| 409 | `SEALED_RECORD_REVISION_CONFLICT` | `revision` is not the record's current revision. `details.current` is the record as it is now. |
| 409 | `SEALED_RECORD_SINGLETON_EXISTS` | The record is `favourites` and the person holds another live `favourites` record. `details.current` is that record. |
| 422 | `SEALED_IDEMPOTENCY_KEY_REQUIRED` | No `Idempotency-Key` header. |
| 422 | `SEALED_IDEMPOTENCY_KEY_INVALID` | The `Idempotency-Key` is not 16 to 128 printable ASCII characters without spaces. |
| 422 | `SEALED_IDEMPOTENCY_KEY_REUSED` | The `Idempotency-Key` was already used for a different call. Mint a new one for a new change. |
| 422 | `SEALED_RECORD_LIMIT_REACHED` | The person already holds the most live records of this kind (`details.kind`, `details.limit`). Delete one to add another. |
| 422 | `VALIDATION_ERROR` | `revision` or `device_id` is missing or invalid, or `record_id` does not match its pattern. |



```bash cURL
curl -X POST "https://api.aitronos.com/v1/sealed-stores/aitronos-browser/records/vSWmWbg9sDur336pnYgYzQ/undelete" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Idempotency-Key: 2bf949c3-71c0-458a-8c76-b9237a22da3c" \
  -H "Content-Type: application/json" \
  -d '{
  "revision": 3,
  "device_id": "1aee2c02-ccac-4ede-b017-1334be895e2e"
}'
```


```python Python
import os
import uuid

import requests

idempotency_key = str(uuid.uuid4())  # once per change; reuse it on every retry

response = requests.post(
    "https://api.aitronos.com/v1/sealed-stores/aitronos-browser/records/vSWmWbg9sDur336pnYgYzQ/undelete",
    headers={
        "Authorization": f"Bearer {os.environ['AITRONOS_TOKEN']}",
        "Idempotency-Key": idempotency_key,
    },
    json={
        "revision": 3,
        "device_id": "1aee2c02-ccac-4ede-b017-1334be895e2e"
    },
    timeout=30,
)
body = response.json()
if response.status_code == 200:
    # The answer is the envelope; read the record for the restored content.
    print("restored at revision", body["revision"])
else:
    print(response.status_code, body["error"]["code"])
```


```javascript JavaScript
const idempotencyKey = crypto.randomUUID(); // once per change; reuse it on every retry
const response = await fetch("https://api.aitronos.com/v1/sealed-stores/aitronos-browser/records/vSWmWbg9sDur336pnYgYzQ/undelete", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.AITRONOS_TOKEN}`,
    "Content-Type": "application/json",
    "Idempotency-Key": idempotencyKey,
  },
  body: JSON.stringify({
    "revision": 3,
    "device_id": "1aee2c02-ccac-4ede-b017-1334be895e2e"
  }),
});
const body = await response.json();
if (response.ok) {
  // The answer is the envelope; read the record for the restored content.
  console.log("restored at revision", body.revision);
} else {
  console.log(response.status, body.error.code);
}
```

**Response:**

200 OK

```json
{
  "object": "sealed_record_envelope",
  "id": "vSWmWbg9sDur336pnYgYzQ",
  "kind": "session",
  "schema_version": 1,
  "revision": 4,
  "created_at": "2026-10-10T08:41:17.204913Z",
  "last_touched_at": "2026-10-10T10:12:31.660152Z",
  "deleted": false,
  "deleted_at": null,
  "device_id": "1aee2c02-ccac-4ede-b017-1334be895e2e",
  "payload_bytes": 112
}
```

409 Not deleted

```json
{
  "success": false,
  "error": {
    "code": "SEALED_RECORD_NOT_DELETED",
    "message": "This item isn't deleted.",
    "system_message": "the record is live; only a tombstone can be undeleted",
    "type": "client_error",
    "status": 409,
    "details": {
      "current": {
        "object": "sealed_record",
        "id": "vSWmWbg9sDur336pnYgYzQ",
        "kind": "session",
        "schema_version": 1,
        "revision": 4,
        "created_at": "2026-10-10T08:41:17.204913Z",
        "last_touched_at": "2026-10-10T10:12:31.660152Z",
        "deleted": false,
        "deleted_at": null,
        "device_id": "1aee2c02-ccac-4ede-b017-1334be895e2e",
        "wrapped_dek": {
          "v": 1,
          "aead": "aes-256-gcm",
          "nonce": "oxwDDz+SyxUEkitE",
          "ct": "UvORUdzuxuE3FMncUQgc4qOEz2QT8a5LarNYrATM0A4Zi1J0aJj9Yu+5ySIKPQHY",
          "epk": "fRXpvCBVDmU9kJ+PSkoqi7NU2Po3FQMK9SbJiz1gOGs="
        },
        "payload": "hWbThAu7J8u8jIcvARYROTja+vbbV4hlntXsIctvvcVdqWGMyTjVt2LgISSfrFORn+gjkJcDsT9l8dsHXoFFCaDLzP06FHLuixGaBMY3WOfWFex4l7SU0G5IKY7DABr74o0l20asWcd9gADrlQl4Zg==",
        "payload_bytes": 112
      }
    },
    "trace_id": "a6568417-2b3e-42ab-81a4-72d32f42999f",
    "timestamp": "2026-10-10T10:13:02.775519Z"
  }
}
```

404 Removed for good

```json
{
  "success": false,
  "error": {
    "code": "SEALED_RECORD_NOT_FOUND",
    "message": "That item isn't synced.",
    "system_message": "no record with this id in this store",
    "type": "client_error",
    "status": 404,
    "details": {},
    "trace_id": "30689beb-2369-49bc-bb15-24be0e5905ba",
    "timestamp": "2026-10-10T10:14:47.290831Z"
  }
}
```

## Related Resources

- [Sealed stores](/docs/api-reference/sealed-stores/introduction)
- [List deleted sealed records](/docs/api-reference/sealed-stores/list-deleted)
- [Delete a sealed record](/docs/api-reference/sealed-stores/delete-record)
- [List a sealed record's revisions](/docs/api-reference/sealed-stores/list-revisions)
- [Get a sealed record](/docs/api-reference/sealed-stores/get-record)