> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentcard.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Report a checkout outcome

> Tell Agentcard what the merchant did with an auto-approved purchase whose charge Agentcard never sees: charged, declined, or refunded.

An auto-approved purchase that finished with `charged_kind: "none"` returned a card token to the merchant's page, and the merchant charges that token later from its own server. Report the charge, a failed charge, or each refund here, with the platform access token of the app that created the purchase. See [Enable auto-approval](/vault/app-auto-approval).

<ParamField path="id" type="string" required>The authorization id.</ParamField>
<ParamField body="outcome" type="string" required>`charged`, `declined`, or `refunded`. Each outcome takes only the fields listed for it, and any other field is refused.</ParamField>
<ParamField body="amount" type="integer">Required on `charged` and `refunded`. A positive amount in the currency's smallest unit (2306 for \$23.06).</ParamField>
<ParamField body="currency" type="string">Required on `charged`: the purchase's ISO 4217 code. A refund takes the charge's currency.</ParamField>
<ParamField body="processor_reference" type="string">The processor's id for the charge, optional on `charged`, or for this refund on `refunded`. Up to 255 characters.</ParamField>
<ParamField body="partner_reference" type="string">`refunded` only. Your own id for this refund when the processor gave you none, the same id on every retry. A refund needs `processor_reference`, `partner_reference`, or both.</ParamField>
<ParamField body="reason" type="string">`declined` only, optional. Why the merchant's charge failed, up to 255 characters.</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.agentcard.sh/api/v2/checkout/authorizations/cauth_2q9d1x8f3k2m4t7w/outcome \
    -H "Authorization: Bearer $ORG_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"outcome": "charged", "amount": 2306, "currency": "usd", "processor_reference": "ch_3Qxample"}'
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "id": "cout_5b5f2c4a0b807ddb7908da4a",
    "object": "checkout_outcome_report",
    "authorization_id": "cauth_2q9d1x8f3k2m4t7w",
    "outcome": "charged",
    "amount": 2306,
    "currency": "usd",
    "processor_reference": "ch_3Qxample",
    "partner_reference": null,
    "reason": null,
    "created_at": "2026-09-26T19:02:11.000Z",
    "replayed": false,
    "authorization": {
      "id": "cauth_2q9d1x8f3k2m4t7w",
      "status": "approved",
      "outcome": {
        "reported_by": "partner",
        "reports": 1,
        "last_reported_at": "2026-09-26T19:02:11.000Z",
        "status": "charged",
        "charged_amount": 2306,
        "refunded_amount": 0,
        "net_amount": 2306,
        "currency": "usd"
      }
    }
  }
  ```
</ResponseExample>

<ResponseField name="replayed" type="boolean">`true` when the report repeats an entry Agentcard already holds. The answer is then `200` with that entry, and nothing is added.</ResponseField>
<ResponseField name="authorization.outcome" type="object">Your account of the purchase so far: `status` (`unreported`, `charged`, `declined`, `refunded`, or `partially_refunded`), `charged_amount`, `refunded_amount`, `net_amount`, `currency`, `reports`, `last_reported_at`, and `reported_by: "partner"`. Every read of the authorization carries the same object.</ResponseField>

A purchase takes one charge or one decline, never both. Refunds come after the charge, one per call, and together they never exceed it. Agentcard tells two refunds apart by their references, never by their amount, so two refunds of the same amount need two references. Agentcard appends each report as its own entry, never edits one, and does not verify what you report. Each new entry sends `checkout_authorization.outcome_reported` to your webhook endpoints.

Only an auto-approved purchase that finished with `charged_kind: "none"` takes a report. Agentcard refuses any other purchase and names the facts that answer it:

```text theme={null}
HTTP 409
{
  "error": {
    "code": "outcome_not_reportable",
    "message": "Only a purchase completed by an autopilot device replay, whose charge Agentcard never sees, takes a reported outcome. This purchase has its own answer: read charged_kind and settlement.",
    "docs": "https://docs.agentcard.sh",
    "status": "approved",
    "execution_mode": "user_approval",
    "autopilot_status": null,
    "charged_kind": "captured"
  }
}
```

Read that purchase with [Get a checkout authorization](/api-reference/vault/authorizations-get): its `charged_kind` and `settlement` say what happened to the charge.

## Errors

| Code | Meaning | What to do |
| - | - | - |
| `400 invalid_request` | The body doesn't match its outcome, or a refund names no reference. | Send only the fields for that outcome, and a reference on every refund. |
| `400 currency_mismatch` | The charge's currency isn't the purchase's. | Report the charge in the `currency` the error names. |
| `400 client_credentials_required` | The call used an API key. | Call with a platform access token. |
| `404 not_found` | No purchase with this id for this app and mode. | Use the `id` that created the purchase, with the token of the app that created it. |
| `409 outcome_not_reportable` | Agentcard sees this purchase's charge itself. | Read `charged_kind` and `settlement` on the authorization. |
| `409 already_charged` | The purchase already has a reported charge. | Report a refund to reduce it. |
| `409 already_declined` | The purchase was already reported declined. | Nothing to add. A charge can't follow a decline. |
| `409 not_charged` | A refund arrived before any charge. | Report the charge first. |
| `409 refund_exceeds_charge` | The refunds would add up to more than the charge. | Refund at most the `remaining_amount` the error names. |
| `409 processor_reference_conflict` | A refund under this `processor_reference` already holds another amount or another `partner_reference`. | Retry with the references the entry holds, or give a second refund its own reference. |
| `409 partner_reference_conflict` | A refund under this `partner_reference` already holds another amount or another `processor_reference`. | Retry with the references the entry holds, or give a second refund its own reference. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.