Developer guide / 01

Delivery + recovery

Delivery outcomes and recovery

Read the completed result before declaring success. If the connection ends early, recover the recorded outcome before deciding whether to resubmit.

ALPHA GUIDECurrent implementationUpdated October 10, 2026

01 / READ THE RESULT

HTTP activity is not delivery completion.

A short Relay or Cache submission returns its usual HTTP status and JSON. For a long-running admitted request, the current implementation starts an HTTP 200 response after five seconds, sets X-OpenPayload-Delivery-Wait: true, and flushes newline keepalives. The completed body contains whitespace followed by one JSON result.

Once response bytes have started, the HTTP status cannot change. Wait for the complete response framing, parse the final JSON, and check its result fields. A heartbeat, HTTP 200 alone, or interrupted JSON does not confirm delivery or storage.

OutcomeWhat it establishes
Live deliveryThe Relay completed the reported socket write. The receiving application still needs to acknowledge processing separately.
Stored fallbackA Cache accepted the reported stored copy. This does not mean the recipient retrieved it.
ProcessingThe node owns work still in progress. Wait or recover its receipt.
FailureThe terminal result reports a failure. Use its status and code to decide what follows.
UnknownCompletion could not be confirmed. Reconcile the outcome before resubmitting.

For a Relay, inspect http_status, success, delivery_mode, and code. For a Cache, require accepted: true and check the terminal status when present. An error or missing acceptance flag is not successful storage. A policy handoff means the next Relay accepted responsibility; it does not confirm later storage.

02 / KEEP THE RECEIPT

Save the handle before a disconnect.

An admitted submission exposes three response headers: X-OpenPayload-Submission-Id for correlation, X-OpenPayload-Receipt-Url for the local result route, and X-OpenPayload-Receipt-Token for authorized access. Preserve them as soon as your HTTP client receives headers.

The receipt token is a bearer credential. Keep it private and use it only with the matching operator endpoint. A result receipt contains outcome metadata, not the original envelope or an acknowledgement from the recipient.

The current alpha retains receipt records for one hour, subject to its bounded record capacity. Missing, invalid, or expired receipt credentials return 404; that does not prove delivery failed.

03 / RECOVER THE OUTCOME

Ask the node what it recorded.

Use GET /relay/submissions/{receiptId} or GET /cache/submissions/{receiptId}, with the receipt token in its request header. Replace the example origin, receipt identifier, and token below with those from the same submission. The example token is a placeholder.

GET https://relay.example.com/relay/submissions/<receiptId>
X-OpenPayload-Receipt-Token: <receipt-token>

An active result returns HTTP 202 with state: processing. A completed result returns HTTP 200 with state: complete, the terminal http_status, and result. Evaluate that nested result using the same success or acceptance rules as the original submission.

{
  "state": "complete",
  "http_status": 202,
  "result": {
    "success": true,
    "delivery_mode": "cache_offload"
  }
}

This is an abbreviated result shape. A node restart can leave a pending record with state: unknown; it does not fabricate success or grant permission to retry. A sender disconnect does not itself cancel processing owned by the node.

04 / DECIDE WHAT FOLLOWS

Reconcile uncertainty before retrying.

  • Wait while a receipt reports processing.
  • For a completed result, inspect its terminal status and success or acceptance fields.
  • For state: unknown or details.outcome_unknown: true, reconcile any protected downstream receipt and use authorized Cache retrieval when available. An unknown outcome is not permission to send another copy.
  • Receipt recovery and deduplication do not establish exactly-once delivery. Your application defines processing acknowledgements and duplicate handling.
  • Acknowledge a retrieved Cache copy only after your client safely persists or processes it.

Android’s sender recognizes terminal results and avoids automatic fallback for explicit unknown outcomes. Automatic receipt recovery remains a client integration task.

Relay API ↗Cache API ↗

Take the protocol in
an unexpected direction.

Explore the public Directory, Relay, and Cache interfaces, then design an application around your own arbitrary payload.

Open developer docs ↗