Decide whether a failed HTTP call may be retried, must be reconciled, or must not be repeated
Given a request's method, how it ended (response status, timeout, reset, refused), idempotency-key evidence and optional caller policy, returns retry / do-not-retry / reconcile / unknown for an agent deciding what to do after a failed tool or API call. Encodes RFC 9110 method idempotency, the proxy and retry-of-a-retry rules and Retry-After parsing; a timeout or reset is never read as success or as safe to repeat for a non-idempotent request. status pass = retry is admissible; fail = do-not-retry or reconcile (see decision); unknown = evidence missing. Does not know any vendor's idempotency-key scope or whether a 429 means unprocessed: those must come from the caller.
What you get
Prevents the double charge, double email and double order that a blind retry of a timed-out POST causes.
Call it
Send the JSON body below to https://agents.writerslogic.com/api/v1/retry-admissibility. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.
curl -i -X POST https://agents.writerslogic.com/api/v1/retry-admissibility \
-H 'content-type: application/json' \
-d '{"method":"POST","ended":"timeout","requestSent":"sent","idempotencyKey":{"present":false}}'
Input
| Field | Type | Required | Description |
|---|---|---|---|
method | string; length 1..32 | yes | HTTP method, case-sensitive (GET, POST, ...). |
ended | string; one of "response", "timeout", "connection-reset", "connection-refused", "dns-failure", "tls-failure", "aborted-by-client" | yes | How the attempt ended. |
status | integer; 100..599 | no | Required when ended is 'response'. |
requestSent | string; one of "unknown", "not-sent", "sent" | no | Whether request bytes reached the network. connection-refused and dns-failure imply not-sent. |
idempotencyKey | object | no | Caller-asserted evidence: the engine knows no vendor's key semantics. |
retryAfter | string; length 0..100 | no | Retry-After header value. |
attempt | integer; 1..1000 | no | 1-based number of the attempt that just ended. Default 1. |
automatic | boolean | no | True when the retry would be issued automatically (library or proxy) rather than by a deliberate decision. |
previousAttemptWasAutomaticRetry | boolean | no | |
actor | string; one of "client", "proxy" | no | |
asOf | string; length 0..40 | no | RFC 3339 instant; needed only to turn a Retry-After HTTP-date into seconds. |
policy | object | no |
Example request body
{
"method": "POST",
"ended": "timeout",
"requestSent": "sent",
"idempotencyKey": {
"present": false
}
}
Result
The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.
| Field | Type | Required | Description |
|---|---|---|---|
status | string; one of "pass", "fail", "unknown", "unsupported" | no | pass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass. |
decision | string; one of "retry", "do-not-retry", "reconcile", "unknown" | no | |
reason | string | no | |
methodClass | string; one of "safe", "idempotent", "non-idempotent", "unknown" | no | |
delaySeconds | integer | no | Wait before retrying, when Retry-After was readable. |
timeoutIsSuccess | boolean | no | Always false. |
witnesses | array<object> | no | |
versions | object | no | Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile). |
limits | array<string> | no | |
deterministic | boolean | no | Always true: pure code, no model. |
Pay and connect
Available through: x402 (USDC on Base), MCP. MCP clients reach it through the execution-safety-kit package.
Machine-readable
- This agent as JSON (schemas, example, OpenAPI operation)
- Free signed sample response
- OpenAPI 3.1 · Catalog · Index of every agent