Contract snapshot 0.101.0 · Deployment and client release availability follow the integration note for your environment.
Eligible receipts
The handoff covers a charged data read whose answer did not arrive, and a charged run that failed. A successful delivery is not refundable on request. A run that delivered nothing was not charged, so there is nothing to refund.
Send a reason with the receipt
Use the receipt identifier and a reason of 1–500 characters. Show the API’s answer, including a refusal, in plain language. An expired returned credit may not become spendable again.
Contract status
The server decides eligibility from the receipt and reason. A refusal is not permission to retry a write automatically.
Prepare the evidence before requesting a refund
Locate the charged receipt and compare its outcome with the result actually received. Explain the delivery failure in the reason, without including credentials or unrelated personal records. An error shown before any charge and an unsuccessful charged delivery are different account states.
Display the decision without rewriting history
Keep the original receipt and show the returned refund outcome separately. Do not remove a ledger entry to make the screen look corrected. Refresh balance and usage after a confirmed result, and preserve the API’s explanation when a receipt is ineligible or an expired credit is not spendable.
POST
/v1/credits/refunds
Refund a charged read, or a failed run, by its receipt
Ask for a charge’s credits back, by its receipt (the id of a `read` or `receipt` entry in GET /v1/credits/usage). A charged Library read is refunded, for example when its response never arrived, unless the same data was read again after the receipt. A charged run is refunded only when it failed (its usage entry has outcome failed); a run that returned nothing was never charged, and a run that delivered is not refunded on request. Refunded once: asking again returns the same refund. A refusal is a 409 refund_refused whose one detail (path body/receiptId) names the reason: charged_nothing, data_reread, run_delivered, or (contract 0.28.0) unlimited_credits: the charge was made under unlimited credits, so its price is on the receipt but nothing was drawn from the balance to give back.
Request body schema
{
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RefundRequest"
}
}
}
}| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Error. The `error.code` is one of: - `invalid_request`: retry advice `fix_request` |
| 401 | Error. The `error.code` is one of: - `key_expired`: retry advice `refresh_credentials` - `key_revoked`: retry advice `refresh_credentials` - `session_expired`: retry advice `refresh_credentials` - `unauthenticated`: retry advice `refresh_credentials` |
| 403 | Error. The `error.code` is one of: - `org_missing`: retry advice `never` - `scope_missing`: retry advice `never` |
| 404 | Error. The `error.code` is one of: - `not_found`: retry advice `fix_request` |
| 409 | Error. The `error.code` is one of: - `refund_refused`: retry advice `never` |
| 429 | Error. The `error.code` is one of: - `rate_limited`: retry advice `after_reset` |
| 500 | Error. The `error.code` is one of: - `internal`: retry advice `bounded` |
| 503 | Error. The `error.code` is one of: - `unavailable`: retry advice `bounded` |
Full response fields and reusable schemas are in the downloadable OpenAPI contract.