# Idempotency & Recovery

## Get Idempotency Record

Retrieves the original request and response for a given idempotency key within the configured TTL window.

```
GET /idempotency/:key
```

### Response — `200 OK`

```json
{
  "idempotency_key": "payment-abc-123",
  "request": {
    "journal_entries": [
      {
        "sequence": 1,
        "type": "PIX_OUT",
        "asset": "BRL",
        "amount": 1000,
        "debit": { "account_id": "...", "balance_policy": "ALWAYS_POSITIVE" },
        "credit": { "account_id": "...", "balance_policy": "ALWAYS_NEGATIVE" }
      }
    ]
  },
  "response": {
    "transaction_id": "019702a0-...",
    "journal_entries": [ ... ]
  },
  "created_at": "2026-01-15T10:30:00.123Z"
}
```

### Errors

| HTTP | Code                        | Cause                               |
| ---- | --------------------------- | ----------------------------------- |
| 404  | `IDEMPOTENCY_KEY_NOT_FOUND` | Key not found or expired (past TTL) |

### Use Cases

* **Debugging duplicate rejections** — when you receive 409, query this endpoint with the conflicting key to see what the original request/response was
* **Reconciliation** — verify whether a specific transaction was processed successfully

### Example

```bash
curl http://<host>:8080/idempotency/payment-abc-123 \
  -H "X-Api-Key: ak_..." \
  -H "X-Api-Secret: sk_..."
```

***

## Get Recovery Records

Returns all records from the last committed batch before the most recent server restart. Used for post-crash reconciliation when the idempotency window may have expired.

```
GET /recovery
```

### Response — `200 OK`

```json
{
  "records": [
    {
      "idempotency_key": "payment-abc-123",
      "request": { ... },
      "response": { ... },
      "created_at": "2026-01-15T10:30:00.123Z"
    },
    {
      "idempotency_key": "payment-def-456",
      "request": { ... },
      "response": { ... },
      "created_at": "2026-01-15T10:30:00.123Z"
    }
  ],
  "count": 2
}
```

### Semantics

| Result                              | Meaning                                            |
| ----------------------------------- | -------------------------------------------------- |
| Record present for your key         | Transaction **was** persisted. Do not retry.       |
| Record absent (key not in response) | Transaction was **not** persisted. Safe to retry.  |
| Empty response (`count: 0`)         | Previous shutdown was clean. Nothing to reconcile. |

### How It Works

On every startup, before accepting any HTTP traffic, the system:

1. Identifies the last committed batch (all records sharing the latest timestamp)
2. Copies those records to the recovery table
3. These records persist until the next restart — no time limit

**Why only the last batch?** Every earlier batch must have received a response (the server was alive long enough to commit a later batch). Only the last batch could have been persisted but not delivered before the process stopped.

### When to Use

* After a server crash or unexpected restart
* When the idempotency window may have expired during downtime
* As part of your startup reconciliation flow

### Example

```bash
curl http://<host>:8080/recovery \
  -H "X-Api-Key: ak_..." \
  -H "X-Api-Secret: sk_..."
```

{% hint style="info" %}
Recovery records have no time limit — they persist from server startup until the next restart. The idempotency endpoint (`GET /idempotency/:key`) is time-limited by the configured TTL. Use recovery when you suspect the TTL may have expired.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://entrytarget.gitbook.io/docs/api-reference/idempotency-and-recovery.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
