---
title: "Record verified non-financial Commerce reconciliation"
method: POST
path: "/commerce/sales/{saleId}/reconciliation"
tags: ["Commerce", "Tickets"]
---

# Record verified non-financial Commerce reconciliation

`POST /commerce/sales/{saleId}/reconciliation`

## Request

- Base URL: `https://platform-api.visitoai.com/m2m/v1`
- URL: `https://platform-api.visitoai.com/m2m/v1/commerce/sales/{saleId}/reconciliation`
- Auth: HTTP bearer

Requires both commerce:sales:read and commerce:sales:reconciliation:write; existing credentials/OAuth grants receive no new scopes. Discover list_tickets with includeCommerce=true, inspect get_ticket purchase evidence, select a human owner, start work, then use the fresh Commerce sourceVersion and a new Idempotency-Key for this intent. The Commerce token is separate from ticket revision. Requires outcome, supporting reference and a note verifying the current issue. Stores a separate reconciliation record without rewriting historical financial records. External reconciliation is not provider-confirmed booking success. Agent/credential identity is audited directly. Built-in Agent approvals remain required. Refunds, payouts and booking retries remain human actions. Commerce completion synchronizes the exact ticket cycle; generic Resolve/Cancel cannot bypass policy. On a stale token (409), read current evidence before deciding a new command. On an uncertain response, read the purchase/ticket first and retry the identical body with the same key only to reconcile the same intent; never blindly create a new intent. Current tenant and test/live mode are fixed by authorization.

## Path parameters

- `saleId` string, required

## Headers

- `Idempotency-Key` string, required

## Request body

- TicketCommerceReconciliationInput
  - `sourceVersion` string, required
  - `outcome` 'completed_externally' | 'verified_no_action_required', required
  - `reference` string, required
  - `note` string, required

## Response `200`

Durable Commerce command result. Read back the exact ticket and purchase after acceptance or uncertainty.

- TicketCommerceReview
  - `tenantId` string, required
  - `purchaseId` string, required
  - `reason` string, required
  - `factsKey` string, required
  - `sourceVersion` string, required
  - `asOf` string, required
  - `title` string, required
  - `itemName` string, required
  - `currency` string, required
  - `purchaseKind` string, required
  - `paymentStatus` string, required
  - `fulfillmentStatus` string, required
  - `refundStatus` string, required
  - `bookingStatus` string
  - `outcome` string
  - `sourceReconciledAt` string
  - `stripeMode` 'test' | 'live', required
  - `cycle` integer, required
  - `revision` integer, required
  - `required` boolean, required
  - `amountMinor` integer, required
  - `historical` boolean, required
  - `providerBookingIds` string[], required
  - `permittedActions` string[], required
  - `humanActions` string[], required
  - `reconciliation` TicketCommerceReconciliation
    - `outcome` 'completed_externally' | 'verified_no_action_required', required
    - `reference` string, required
    - `note` string, required
    - `actor` TicketCommerceActor, required
      - `id` string, required
      - `type` 'operator' | 'agent', required
      - `name` string
    - `at` string, required
  - `lastCommand` TicketCommerceCommand
    - `id` string, required
    - `action` 'fulfill' | 'reconcile', required
    - `actor` TicketCommerceActor, required
      - `id` string, required
      - `type` 'operator' | 'agent', required
      - `name` string
    - `at` string, required
  - `source` object, required
    - `conversationId` string
    - `conversationKey` string
    - `channel` string
    - `propertyId` string
  - `bookingConfirmed` boolean, required: True only for successful provider booking state plus required stored provider identifiers; reconciliation alone never sets this.

## Other responses

- `400`: Invalid request.
- `401`: Authentication required.
- `403`: Required Commerce permission missing.
- `404`: Resource unavailable in this workspace.
- `409`: State, revision or idempotency conflict.
- `502`: Uncertain Commerce outcome; inspect source state before retrying the same intent.
- `503`: Capability unavailable.

---

[API](https://skmtc.dev/visitoai/apis/visito-m2m-api.md) - [All operations](https://skmtc.dev/visitoai/apis/visito-m2m-api/llms.txt) - [OpenAPI document](https://skmtc.dev/visitoai/apis/visito-m2m-api/revisions/98377d35c234?raw)
