# PennyBot delivery and recovery

All 13 listed services use durable order storage. Normal processing is automatic within the paid API request. Recovery retrieves the original result; it is separate from producing new work and from establishing payment finality.

## Before a signed purchase

Keep the exact original method, endpoint/query, Content-Type, raw request body bytes, and signed PAYMENT-SIGNATURE. For POST requests, serialize once and retain those exact bytes; reordering JSON fields, whitespace, or headers covered by the request binding can change the request identity.

Choose a fresh cryptographically random Idempotency-Key of 32–128 ASCII letters, digits, underscores or hyphens. Send it with the signed purchase and preserve it privately. It is a bearer recovery credential. Never use a predictable key, reuse it for another order, include it in a URL, log it, or publish it with example data. No account or conventional API key is required to buy.

## First delivery

Retain the response bytes plus X-PennyBot-Order, X-PennyBot-Settlement, X-PennyBot-Result-SHA256, and any PAYMENT-RESPONSE. Check the product's output schema and billing rule. Compare SHA-256 over the exact returned bytes with X-PennyBot-Result-SHA256 when supplied. JSON fee_eligibility describes product eligibility and is not an on-chain settlement receipt.

## Exact replay after an uncertain response

Send the same original request, same original signed authorization and same original Idempotency-Key. Do not create a fresh authorization simply because a response was lost. If the original order exists, exact replay returns its stored bytes without rerunning the service or submitting a second settlement. Changed input under a used identity is rejected. Without an explicit key, the same signed authorization and original input can identify the original order, but the separate order-ID recovery route requires the original explicit key.

Price or schema updates do not rewrite existing orders. Authenticated exact replay of a known original order is resolved before current purchase-term validation and retains that order's original price, schema and response bytes. For example, an original Product 13 order at 100,000 atomic can replay its historical 100,000-atomic result; the advertised 4,000-atomic price applies to a new purchase. A keyless replay must preserve the exact original signed payment payload and request binding; merely sharing a payer/nonce is insufficient. The current standalone product schema describes new purchases; the OpenAPI Product 13 response also includes the historical-price replay shape.

This is recovery of one purchase. It is not a promise that every failed order completes, that an absent response was free, or that the same result is fresh for a new task. If the original signed request never reached an accepted order, replaying it can start that original authorized purchase; it does not create a second authorization. The order-ID GET recovery route only reads/reconciles the original order.

The configured result-retention window is **15 minutes from durable result preparation**, not delivery or acknowledgment. Unresolved settlement can delay deletion; late reconciliation does not grant a fresh 15-minute window. Save your local result promptly. Storage failure, host availability and order state still limit recoverability; indefinite availability is not guaranteed. Financial history/tombstones and retained result bytes are separate records.

## Recover by order ID

Mainnet: GET https://playbrightgaming.com/agent-services-mainnet/recover/{order_id}

Testnet: GET https://playbrightgaming.com/agent-services/recover/{order_id}

Send the original private Idempotency-Key header. Send no body and no query parameters. Recovery reconciles the original payment identity read-only when needed. Retained original output can be returned while X-PennyBot-Settlement remains settlement_uncertain; output availability is not proof that settlement succeeded. No second PAYMENT-RESPONSE is emitted on replay.

- Original product result/status with result hash: validate the original bytes and inspect settlement separately.
- HTTP 202: the original work is still processing. Poll conservatively using the same order identity; do not buy another copy automatically.
- HTTP 409: changed request, terminal failure, or no retained output for the order state. Read the fixed state/reason; preserve evidence.
- HTTP 410 with {"order_id":"ord_...","error":"retained_output_expired"}: the original retained result has expired. Purchase-route replay and order-ID recovery return order/settlement headers without a result-hash header or a second PAYMENT-RESPONSE. Do not infer a refund or create another purchase automatically.
- HTTP 400/403: malformed or unauthorized recovery credentials/request.
- HTTP 503: storage, retained output or reconciliation is unavailable. Preserve the original identity for investigation.

Some retained no-charge product failures replay with their original non-200 status. Missing storage or incomplete input cannot promise retained bytes. No generic automatic refund, escrow, instant finality, or 100% recovery guarantee is made.

## Optional received-hash acknowledgment

POST https://playbrightgaming.com/agent-services-mainnet/ack/{order_id} (or the testnet /agent-services prefix), with the original Idempotency-Key and X-Result-SHA256 containing the exact 64-character lowercase response hash. Send no body/query. This records authenticated receipt of that exact hash; it does not mean satisfaction, freshness, truth, or another payment authorization.

The acknowledgment path does not promise HTTP 410 after expiry; unavailable retained bytes can instead produce HTTP 503 because the hash cannot be read back. A local saved result remains separate from server retention.

## Helpers and incidents

The updated [URL-check buyer](https://playbrightgaming.com/agents/pennybot-buyer.mjs) saves a private recovery context before its signed request. The [recovery helper](https://playbrightgaming.com/agents/pennybot-recover.mjs) replays that original context without loading a wallet or creating a signature:

```sh
node pennybot-recover.mjs pennybot-private-recovery-REPLACE-WITH-YOUR-FILE.json
```

Keep the context in an access-controlled private folder. The file contains a bearer key and signed authorization; POSIX mode flags alone do not configure a Windows folder ACL. Never upload it or send it to support. The generic [inspection helper](https://playbrightgaming.com/agents/pennybot-inspect.mjs) handles unsigned checks for all 13 services and never pays.

For unresolved incidents use the existing [Bright Gaming contact form](https://playbrightgaming.com/contact_page.php). Share only the order ID, UTC time, public endpoint, result hash, transaction ID and redacted error/state. Do not share keys, recovery files, signatures, credentials or sensitive submitted content. This is a human contact channel, not a guaranteed automated recovery SLA.
