Idempotency & retries
Why retrying any request is safe, and how to name items so that a retried add never adds anything twice.
Networks fail. A request can time out after the server committed it. twin memory is built so that sending the same request again changes nothing the first one did not.
The item id is the identity
An item's id decides which item it is. Sending an item with an id memory already holds is the same item, not
a second one:
- the same content again changes nothing;
- different content is an edit.
So the simplest rule is: give every item a stable id from your own system, such as your message id, and
retry freely.
Items without an id
If your items have no ids, send an Idempotency-Key header with the add:
curl https://api.twinmemory.dev/v1/memory/add \
-H "Authorization: Bearer $TWIN_MEMORY_API_KEY" \
-H "X-Twin-Account: user_42" \
-H "Idempotency-Key: batch-7" \
-H "Content-Type: application/json" \
-d '{ "items": [{ "text": "hello there" }] }'Each item without an id is then named by the key and its place in the batch: the first is batch-7:0, the
second batch-7:1, and so on. A retry with the same key and the same items in the same order is the same
items again.
{
"items": [{ "id": "batch-7:0", "event_id": "ev_4e787041d539c3d4", "landed": false }],
"queued": 1,
"pending": 1
}- Items that have an
idkeep it; the key does not rename them. - The key is trimmed and cut to 200 characters.
- Use a new key for each new batch, such as a UUID made when the batch is built, and reuse it only to retry.
Without an id and without a key, an item with an at is named by its words, author, session and time, so the
same words at the same time are the same item. An item with neither an id, a key nor an at gets a random id,
and a retry adds it twice.
No stored replies
twin memory does not store responses to replay them. A retried request runs again. Because it names the same
items, it changes nothing, and its response describes the same items with the same event_ids.
Retrying other routes
- Reads (
search,grep,readand the rest) change nothing. Retry them freely. forgetof something already forgotten erases nothing more. The second receipt counts zero events. If a receipt says"queue": null, call forget again to clear the queue.correctof a record already retracted answers404, because the record is no longer held. Treat that as done.
Times and offsets
An item's time is part of its identity when it is first stored. Once memory holds an id, later sends keep the
first time, whatever at they carry.
For items without an id, the time is part of the name. 09:00+09:00 and 00:00Z are the same instant but
not the same text, so they name two items. Send stable ids and this cannot happen.
When to retry
| Status | Retry? |
|---|---|
503 | Yes, after Retry-After seconds when present, otherwise with backoff. |
| Network error or timeout | Yes. |
400, 401, 403, 404, 413, 422 | No. Fix the request. A 404 on a read means the end user has no memory yet. |