THE INTRO CARD is free — what an AI skill card is and how to use one Download →Lost Lauren, contact us

THE INSTRUMENTS · Nº 968 · EDITION 1 · LAUNCHING SOON

LUND CARDS · THE INSTRUMENTSNº 968
THE RETRY CARD — the LSC-1 face
THE CARD AS TEXT · FOR EYES AND FOR MACHINES

THE RETRY CARD · the retry review · what to retry, how long to wait, what never to repeat

WAKES WHEN 429 or 529 errors break a batch or an agent, someone asks which errors to retry, a retry loop is written or reviewed, calls hang past a deadline, or a retry might send or charge twice

THE METHOD

  1. policy retry-policy.json — the policy against the error table, the waits, the worst case, every finding with its fix.
  2. trace error-log.jsonl --policy retry-policy.json — a real night replayed, call by call.
  3. simulate --policy … --scenario … --runs N --seed S — policies compared on the same made-up draws.
  4. table — the error facts and the SDK facts, with their pages and dates.
  5. The team changes the policy and checks it again.

REFUSES

  • Retry rules from memory
  • Advising a retry of an error that never clears
  • Presenting a simulation as a measurement
  • Ignoring a side effect a retry would repeat

IT MAKES policy — a retry policy against the API's errors; exit 1 on any ERROR; trace — replay an error log, call by call; exit 1 on any ERROR; simulate — the policy against a made-up scenario, seeded; table — the error table and the SDK facts, with sources and dates.

THE LAW The error facts are dated data from the docs, never memory. What never clears is never retried; retry-after is the least wait. A timeout may have run: a side effect is retried only under an idempotency key. The worst case is computed, printed with its formula, and set against the deadline. A simulation is made up; a log is real. The policy is the team's; the card proposes.

IN THE BOX scripts/retry.py · assets/api-rules.json · the formats · the error table and checks · the method by hand · the sources · ten tests.

PROOF selftest 28/28; a nightly batch job's policy (10 ERROR), its night replayed (11 ERROR), the fixed policy, and the trigger test, on the record (WITNESS.md) · witnessed 2026-10-13 · EDITION 1.

THE SEAL 96 of 100 · LEGENDARY · WITNESSED · Trigger 5 · Machinery 5 · Law 5 · Portability 5 · Proof 4

IT CAN BE WRONG an AI reading a text file: it can be wrong and can invent a number, a rule, a name or a date; check what matters against your own records and the source; the risk is yours. LICENSE-NOTE.md rides in the packet and is the licence.

THE PUNCH · SHA-256 OF SKILL.MD · B55BF7A640463BE42F2B8C29

THE FACE, FULL SIZE → · THE MACHINE FACE → · card.json →

THE RETRY CARD

the retry review · what to retry, how long to wait, what never to repeat

POLICY · TRACE · SIMULATE · TABLE

96LEGENDARYWITNESSEDIN CLAUDEIN LUNDRIN CHATGPT

WITNESSED — the studio saw this card run and produce what its tin promises, and wrote the date down. What the marks mean →

THE SPEC SHEET · READ BEFORE YOU BUY · THE STANDARD EVERY CARD MEETS →

SEAL
96 of 100 · LEGENDARY · WITNESSED
EDITION
E1 · witnessed 2026-10-13
MACHINE
scripts/retry.py · 4 commands · selftest 28/28
RUNS
On your own computer. Standard library only, offline; no account, no key, no telemetry.
HOSTS
Claude · Claude Code · ChatGPT · Gemini · any AI that reads a file (HOSTS.md names each door)
LICENCE
One person, any number of their own AIs and computers · editions replace files · nothing renews · freeze, not loss
PUNCH
B55BF7A640463BE42F2B8C29 · sha-256 of SKILL.md · check any file against it →

CITE THIS CARDTHE RETRY CARD, Edition 1. Lund Studio LLC, Westminster, Colorado. https://lundr.tech/?view=retry-card. Punch B55BF7A640463BE42F2B8C29. Retrieved 2026-10-13.

What it is.

A review of how an app retries failed Claude API calls, before it ships and after a bad night. Against the API's errors as read from the docs, it finds:

Use it whenever 429 or 529 errors break a batch or an agent, someone asks which errors to retry, a retry loop is written or reviewed, calls hang past a deadline, or a retry might send or charge twice. Not for testing against a stand-in service (THE DRY RUN CARD), Claude Code in CI (THE HEADLESS CARD), repeated work as skills (THE REPEAT CARD), raising rate limits.

It carries a machine that shows its working: policy — a retry policy against the API's errors; exit 1 on any ERROR; trace — replay an error log, call by call; exit 1 on any ERROR; simulate — the policy against a made-up scenario, seeded; table — the error table and the SDK facts, with sources and dates — 28 checks in its selftest.

It answers requests such as “529 overloaded errors keep killing our batch job”, “which Anthropic API errors should we retry?”, “we retry five times with a fixed two-second wait: is that fine for 429s?”, “the SDK retries twice and we wrap it in our own loop: how many requests is one call?”, “if the call times out after the agent sent the email, does a retry send it twice?”.

Six laws, written into the card.

They are in the card itself, so the AI follows them.

THE ERROR FACTS ARE DATED DATA FROM THE DOCSThe error facts are dated data from the docs, never memory.
WHAT NEVER CLEARS IS NEVER RETRIEDWhat never clears is never retried; retry-after is the least wait.
A TIMEOUT MAY HAVE RUNA timeout may have run: a side effect is retried only under an idempotency key.
THE WORST CASE IS COMPUTEDThe worst case is computed, printed with its formula, and set against the deadline.
A SIMULATION IS MADE UPA simulation is made up; a log is real.
THE POLICY IS THE TEAM'SThe policy is the team's; the card proposes.

The method.

  1. policy retry-policy.json — the policy against the error table, the waits, the worst case, every finding with its fix.
  2. trace error-log.jsonl --policy retry-policy.json — a real night replayed, call by call.
  3. simulate --policy … --scenario … --runs N --seed S — policies compared on the same made-up draws.
  4. table — the error facts and the SDK facts, with their pages and dates.
  5. The team changes the policy and checks it again.

What rides in the card.

In the card’s own voice, with a machine that shows its working.

THE REFERENCESreferences/POLICY-FORMAT.md · SOURCES.md · THE-ERRORS.md · THE-METHOD.md
THE MACHINEscripts/retry.py · four commandspolicy — a retry policy against the API's errors; exit 1 on any ERROR; trace — replay an error log, call by call; exit 1 on any ERROR; simulate — the policy against a made-up scenario, seeded; table — the error table and the SDK facts, with sources and dates. 28 checks in its selftest. Needs: Python 3; the retry policy as JSON, and an error log if there is one.

What it does once your AI has it.

  • policy A retry policy against the API's errors; exit 1 on any ERROR
  • trace Replay an error log, call by call; exit 1 on any ERROR
  • simulate The policy against a made-up scenario, seeded
  • table The error table and the SDK facts, with sources and dates
  • On the record Example Co's nightly batch: its policy (10 ERROR, 15 requests a call), one night replayed (11 ERROR, an email sent twice), and the fixed policy; 39 of 48 in the trigger test after the rewrite

What it refuses, and where it hands off.

It refuses retry rules from memory; advising a retry of an error that never clears; presenting a simulation as a measurement; ignoring a side effect a retry would repeat.

  • testing code against a stand-in service that fails on purpose → THE DRY RUN CARD
  • running Claude Code in CI → THE HEADLESS CARD
  • turning repeated work into skills → THE REPEAT CARD
  • raising rate limits → the account's own contact with the platform

The policy as written, not the code that runs it; the error facts were read 2026-10-12 and change; a simulation is not a measurement. It is an AI reading a text file: it can be wrong, so check what matters against your own records and the source.

What’s in the buy.

  • CARD.md — the whole card: its boot, law, method, machine, seals, refusals and hand-offs, ledger, score and what it carries · SKILL.md — the door your AI reads first · START-HERE.md — the first five minutes, for you
  • POLICY-FORMAT.md + SOURCES.md + THE-ERRORS.md + THE-METHOD.md — in references/, in the card's own voice
  • scripts/retry.py — the machine: policy · trace · simulate · table; see NEEDS below; selftest 28/28
  • WITNESS.md — the run on a realistic case as printed, and the trigger test on Haiku, Sonnet and Opus · SELFTEST.md — the machine's own test, as run at the cut · AUDIT.md, the twelve checks · MANIFEST.md, every file hashed
  • tests/evals.json — the cases it must take, hand off and refuse
  • MY-LEDGER.md — the card's memory, on your own machine · TIN.md, the nine lines on the tin · LICENSE-NOTE.md · HOSTS.md, where it runs
  • system/short-prompt.md and system/system-prompt.md — the doors for any AI without skills

PROOF · SELFTEST 28/28 · WITNESSED ON A RUN · TRIGGER TEST 36 OF 48 ON ITS OWN PROMPTS · HAIKU 4/16 · SONNET 16/16 · OPUS 16/16 · 0 WRONG PICKS · EDITION 1 · PUNCH B55BF7A640463BE42F2B8C29

ON EVERY DOOR · A CARD FOR YOUR AI, A FILE FOR YOUR COMPUTER

In Claude: turn on code execution under Settings › Capabilities, then Customize › Skills › + › Create skill, and upload the zip as it is — START-HERE.md in the box walks you through it, and tells you how to keep the ledger. In ChatGPT, Gemini and the rest: a Project, a GPT or a Gem with the card’s files attached and the short door in the box pasted as its instructions. The words run anywhere an AI reads Markdown; the machines run wherever the host runs Python. Witnessed in Claude only. The host marks →

Take it.

Nº 968 — LAUNCHING SOON

Sold as is under the term printed. A card instructs an AI you operate; results depend on your model, your files and your judgement. Not medical, legal, tax or financial advice, never the person’s boss, and not a licence to practise. The terms →

ONE PAYMENT · NOTHING RENEWS ITSELF

OFFLINE · ONE LICENCE · PUNCH-CHECKABLE · THE STANDARD

One payment. The file is yours to keep and keeps working at its edition; new editions issued in the year after you buy reach you by email as replacement files. Tax is added at checkout where it applies. Nothing auto-renews.

One email when it is on sale, from the studio; nothing else, ever.

A TERM, NOT A SUBSCRIPTION: NOTHING RENEWS ITSELF AND NOBODY IS CHARGED AGAIN. WHEN A TERM ENDS THE FILES STAY ON YOUR COMPUTER AND STAY READABLE — FREEZE, NOT LOSS.

THE MACHINE · IN THE OPEN · FROM THE CARD’S OWN WITNESS.MD AND SELFTEST.MD

retry.py, every command showing its working.

A small Python program. Your AI runs it; you can too. The blocks below are pasted from the card’s own record, as printed.

policya retry policy against the API's errors; exit 1 on any ERROR
tracereplay an error log, call by call; exit 1 on any ERROR
simulatethe policy against a made-up scenario, seeded
tablethe error table and the SDK facts, with sources and dates
selftest28 checks that prove the machine; it must print 28/28
python3 scripts/retry.py policy team-policy.json
RETRY POLICY CHECK · team-policy.json · rules as read 2026-10-12

WHAT IT RETRIES, AGAINST THE API'S ERRORS
  status         type                     the docs say       this policy
  400            invalid_request_error    NEVER              retries   ← wrong
  401            authentication_error     NEVER              retries   ← wrong
  402            billing_error            NEVER              retries   ← wrong
  403            permission_error         NEVER              retries   ← wrong
  404            not_found_error          NEVER              retries   ← wrong
  409            conflict_error           AFTER FIX          retries
  413            request_too_large        NEVER              retries   ← wrong
  429            rate_limit_error         RETRY AFTER        retries
  429 spend cap  rate_limit_error         NEVER              retries   ← wrong
  500            api_error                RETRY              retries
  504            timeout_error            RETRY              retries
  529            overloaded_error         RETRY              retries
  stream         overloaded_error         RETRY              (not streaming)
  connection     -                        RETRY · AMBIGUOUS  retries
  timeout        -                        RETRY · AMBIGUOUS  retries
  408            -                        RETRY              retries
  5xx            -                        RETRY              retries

FINDINGS
  ERROR P1   retries 400 invalid_request_error: the format or content of the request is wrong, or a spend limit you set was reached: it fails the same way until that changes
             fix: add it to never_retry
  ERROR P1   retries 401 authentication_error: the key is malformed, revoked or expired
             fix: add it to never_retry
  ERROR P1   retries 402 billing_error: billing or payment details need attention
             fix: add it to never_retry
  ERROR P1   retries 403 permission_error: the key may not use this resource
             fix: add it to never_retry
  ERROR P1   retries 404 not_found_error: the path or a resource id does not exist
             fix: add it to never_retry
  ERROR P1   retries 413 request_too_large: over the maximum request size (Messages 32 MB, Batch 256 MB): shrink the request
             fix: add it to never_retry
  ERROR P1   retries 429 (the spend cap): the tier's monthly spend cap: no retry-after header, and every retry (the SDK's included) fails until access resumes
             fix: set spend_cap_stop: true
  ERROR P4   retries 429 without honouring retry-after: the docs say retry-after gives the seconds to wait and earlier retries will fail
             fix: set honor_retry_after: true (wait at least retry-after)
  ERROR P11  worst case 15 min 8 s is over the caller's deadline of 2 min 0 s
             fix: set stop_at_deadline: true (no wait or attempt starts past the deadline, and an attempt's timeout is the time left), or cut attempts and timeout
  ERROR P14  side effects are unsafe and the policy retries errors where the first try may have run (connection, timeout, 500, 504, 529, 5xx, 408): a retry can send, charge or write twice
             fix: retry the model call, not the turn: run each side effect once, under an idempotency key your own system checks (idempotency_key: true)
  WARN  P6   multiplier 1: a fixed wait, not exponential backoff; every retry arrives as fast as the last
             fix: use 2
  WARN  P9   no jitter: clients that failed together retry together, and fail together again
             fix: use full jitter
  WARN  P13  stacked retries: 5 attempts here × (2 SDK retries + 1) = 15 requests for one call
             fix: retry in one place: set the SDK's max_retries to 0 under your loop, or drop your loop
  NOTE  P3   retries 409 conflict_error; the docs say to resolve the conflict first, so a blind retry usually conflicts again
             fix: retry 409 only after reading the resource's state

THE WAITS · base 2 s · ×1 per retry · cap 2 s · jitter none
  before retry 1      2.00 s to    2.00 s  (expected 2.00 s; longest waits so far 2.00 s)
  before retry 2      2.00 s to    2.00 s  (expected 2.00 s; longest waits so far 4.00 s)
  before retry 3      2.00 s to    2.00 s  (expected 2.00 s; longest waits so far 6.00 s)
  before retry 4      2.00 s to    2.00 s  (expected 2.00 s; longest waits so far 8.00 s)

WORST CASE · 5 attempts × (2 SDK retries + 1) × 1 min 0 s timeout + 8.0 s of waits = 15 min 8 s against a deadline of 2 min 0 s
REQUESTS · at most 15 for one call

VERDICT · FAIL · 10 ERROR · 3 WARN · 1 NOTE
[… 3 more lines, trimmed here]
python3 scripts/retry.py trace last-night.jsonl --policy team-policy.json
RETRY TRACE · last-night.jsonl against team-policy.json · 5 calls · rules as read 2026-10-12

call T-1041 · succeeded · 5 attempts · 15.7 s
   1  t=    0.0 s  429         rate_limit_error         RETRY AFTER        ra=12     waited=2.0    retried after 2.0 s; retry-after said 12.0 s
   2  t=    2.4 s  429         rate_limit_error         RETRY AFTER        ra=10     waited=2.0    retried after 2.0 s; retry-after said 10.0 s
   3  t=    4.8 s  429         rate_limit_error         RETRY AFTER        ra=7      waited=2.0    retried after 2.0 s; retry-after said 7.0 s
   4  t=    7.2 s  429         rate_limit_error         RETRY AFTER        ra=5      waited=2.0    retried after 2.0 s; retry-after said 5.0 s
   5  t=    9.6 s  200         -                        OK                 ra=-      waited=-      
call T-1042 · failed · 5 attempts · 9.5 s
   1  t=    0.0 s  400         invalid_request_error    NEVER              ra=-      waited=2.0    retried a 400 invalid_request_error
   2  t=    2.3 s  400         invalid_request_error    NEVER              ra=-      waited=2.0    retried a 400 invalid_request_error
   3  t=    4.6 s  400         invalid_request_error    NEVER              ra=-      waited=2.0    retried a 400 invalid_request_error
   4  t=    6.9 s  400         invalid_request_error    NEVER              ra=-      waited=2.0    retried a 400 invalid_request_error
   5  t=    9.2 s  400         invalid_request_error    NEVER              ra=-      waited=-      stopped on a 400: right
call T-1043 · succeeded · 2 attempts · 14.1 s
   1  t=    0.0 s  529         overloaded_error         RETRY              ra=-      waited=2.0    
   2  t=    7.8 s  200         -                        OK                 ra=-      waited=-      
call T-1044 · succeeded · 2 attempts · 121.2 s
   1  t=    0.0 s  timeout     -                        RETRY · AMBIGUOUS  ra=-      waited=2.0    a side effect ran, then the call was retried
   2  t=   63.0 s  200         -                        OK                 ra=-      waited=-      
call T-1045 · failed · 2 attempts · 2.4 s
   1  t=    0.0 s  429         rate_limit_error         NEVER              ra=-      waited=2.0    retried a 429 rate_limit_error (the spend cap)
   2  t=    2.2 s  429         rate_limit_error         NEVER              ra=-      waited=-      stopped on a 429 (the spend cap): right

FINDINGS
  ERROR T2  call T-1041 · attempt 1: retried after 2.0 s though retry-after said 12.0 s; the docs say earlier retries will fail
  ERROR T2  call T-1041 · attempt 2: retried after 2.0 s though retry-after said 10.0 s; the docs say earlier retries will fail
  ERROR T2  call T-1041 · attempt 3: retried after 2.0 s though retry-after said 7.0 s; the docs say earlier retries will fail
  ERROR T2  call T-1041 · attempt 4: retried after 2.0 s though retry-after said 5.0 s; the docs say earlier retries will fail
  ERROR T1  call T-1042 · attempt 1: retried a 400 invalid_request_error, which fails the same way every time
  ERROR T1  call T-1042 · attempt 2: retried a 400 invalid_request_error, which fails the same way every time
  ERROR T1  call T-1042 · attempt 3: retried a 400 invalid_request_error, which fails the same way every time
  ERROR T1  call T-1042 · attempt 4: retried a 400 invalid_request_error, which fails the same way every time
  ERROR T5  call T-1044 · attempt 1: a side effect ran and the call was retried, so it may run twice
  ERROR T8  call T-1044 · the call ran 121.2 s, past the caller's deadline of 120.0 s
  ERROR T1  call T-1045 · attempt 1: retried a 429 rate_limit_error (the spend cap), which fails the same way every time

VERDICT · FAIL · 11 ERROR · 0 WARN · 0 NOTE
FORMULA · each failed attempt is classed by the error table; the wait = the logged wait_s, or the next attempt's start − this start − its duration; a retry before retry-after, a retry of a NEVER error or a retry after a side effect is an ERROR.
SOURCE · the log you gave; errors platform.claude.com/docs/en/api/errors; retry-after platform.claude.com/docs/en/api/rate-limits · read 2026-10-12.
LIMIT · without durations, the gap between starts includes the attempt itself, so an early retry can be missed but is never invented; HTTP-date retry-after values are not read.
THE SELFTEST, AS PRINTED
PASS the table: 400, 401, 402, 403, 404 and 413 are never retried; 500, 504, 529 and stream errors are
PASS a 429 with retry-after waits for it; the spend-cap 429 is never retried; a 429 with neither is flagged
PASS connection errors and timeouts are retryable but ambiguous; 502 is a 5xx; 422 is never retried
PASS a sound policy passes with no ERROR and no WARN
PASS retrying 'any' is an ERROR for each error that never clears, the spend cap included
PASS retrying 429 without honouring retry-after is an ERROR
PASS a fixed wait and no jitter are WARNs
PASS stacked retries: 5 attempts × (2 SDK retries + 1) = 15 requests
PASS unsafe side effects retried on ambiguous errors without a key are an ERROR
PASS the worst case of 15 tries of 10 minutes is over a 30 s deadline, an ERROR
PASS dropping 529 and connection errors is a WARN for each
PASS waits: base 1 s doubling to a 30 s cap gives 1, 2, 4, 8, 16 s (31 s in all)
PASS jitter ranges: full 0..d, equal d/2..d, decorrelated base..min(cap, base × 3^k)
PASS worst case: 4 × 600 s + 1 + 2 + 4 = 2,407 s; stop_at_deadline caps it at 30 s; an uncapped retry-after leaves it unbounded
PASS streaming without retrying stream error events is a WARN
PASS with an idempotency key the side-effect ERROR clears
PASS trace: a retried 400 is an ERROR
PASS trace: a retry 3 s after a retry-after of 20 s is an ERROR; waiting 18 s for 17 s is not
PASS trace: the spend-cap 429, read from the error body, retried, is an ERROR
PASS trace: a side effect followed by a retry is an ERROR
PASS trace: giving up after one 529 is a WARN; a call past its 30 s deadline is an ERROR
PASS simulate: the same seed gives the same numbers; ignoring retry-after sends retries that meet the 429 again, honouring it sends none
PASS simulate: under the spend cap nothing succeeds; retrying 'any' wastes 4 retries a call, a policy that stops on it wastes none
PASS a policy it cannot read exits 2 and names every bad field with what is allowed, never a crash
PASS the command line: a sound policy exits 0, a bad one 1; simulate writes a log that trace reads, call for call; --help shows usage
PASS the same policy gives the same report, byte for byte
PASS assets/api-rules.json matches the rules built into this machine
PASS nothing in this machine opens a network connection
selftest 28/28

THE TRIGGER TEST. The card's line was tried on Haiku, Sonnet and Opus beside 14 neighbouring skills, in a clean environment: 36/48 on its own prompts (Haiku 4/16 · Sonnet 16/16 · Opus 16/16), 0 wrong picks; no skill (answered directly) 12.

THE RUNS ARE PASTED FROM THE CARD’S OWN RECORD AS PRINTED. THE CASES ARE THE STUDIO’S OWN EXAMPLES (EXAMPLE CO IS FICTION); NO PRIVATE PERSON IS NAMED.

QUESTIONS AT THE TABLE

Asked before the wire.

What does it need from me?

Python 3; the retry policy as JSON, and an error log if there is one.

Does it send anything anywhere?

Its machine reads what you point it at, and HOSTS.md says what it needs; python 3; the retry policy as JSON, and an error log if there is one. The words run wherever an AI reads Markdown.

What is on the record?

The selftest (28/28), a run on a realistic case with every command and verdict pasted into WITNESS.md as printed (Example Co's nightly batch: its policy (10 ERROR, 15 requests a call), one night replayed (11 ERROR, an email sent twice), and the fixed policy; 39 of 48 in the trigger test after the rewrite); and the trigger test, the card's line tried on Haiku, Sonnet and Opus beside 14 neighbouring skills: 36/48 on its own prompts, 0 wrong picks; the twelve-check audit (AUDIT.md). The punch on the face is the SHA-256 of SKILL.md, so a downloaded copy can be checked against this room.

Can it be wrong?

Yes — it is an AI reading a text file. The policy as written, not the code that runs it; the error facts were read 2026-10-12 and change; a simulation is not a measurement.

What will it never do?

It refuses retry rules from memory; advising a retry of an error that never clears; presenting a simulation as a measurement; ignoring a side effect a retry would repeat.

Who may use it?

One person, any number of their own AIs and computers; a team needs a company licence.

← THE INSTRUMENTS · THE FLOOR →

AT YOUR ELBOW, NEVER THE BOSS · NOT LEGAL, MEDICAL, TAX OR FINANCIAL ADVICE · NOT A PAYMENT CARD · © 2026 LUND STUDIO LLC

PAY BYAmerican Express Apple Pay Diners ClubDiscoverGoogle Pay Mastercard PayPalShop Pay Visa
CART · 0