post_finance_payouts_reconcile

Changes data · you confirm first

Calls POST /api/finance/payouts/reconcile as the signed-in person · REST reference

Reconcile settled payouts against Stripe (platform staff)

For every settled payout still PENDING or FAILED, asks Stripe whether the transfer actually happened and promotes confirmed rows to SENT. Never creates a transfer and never writes FAILED. Defaults to a dry run — pass dryRun: false to commit the promotions.

Arguments

ArgumentTypeDescription
bodyJSONobjectThe request body, as a JSON object. Its fields are listed below.

Fields of body

FieldTypeDescription
dryRunbooleanAsk Stripe and report, but write nothing
limitintegerMax settlements to examine in one pass (DAL default 100)
minAgeSecondsintegerIgnore settlements younger than this (default 900)

Example call

A client sends this over the MCP session; Claude and other agents build it for you. The values are placeholders — the shape is real.

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "post_finance_payouts_reconcile",
    "arguments": {
      "body": {
        "dryRun": true,
        "limit": 1,
        "minAgeSeconds": 1
      }
    }
  }
}
Confirmation
The client shows the person the exact request and waits. Nothing runs until they tick Make this change. See Reading and changing.

Result

On success (HTTP 200) the tool returns one text item holding the API's JSON, pretty-printed.

Per-settlement reconciliation report

json
{
  "amountMismatched": 1,
  "confirmedSent": 1,
  "dryRun": true,
  "rows": [
    {
      "amount": 1,
      "currency": "string",
      "error": "string",
      "offsetForClawbackId": "string",
      "orgId": "string",
      "orgName": "string",
      "outcome": "CONFIRMED_SENT",
      "previousState": "string",
      "stripeAmount": 1,
      "stripeDestination": "string",
      "stripeTransferId": "string",
      "transactionId": "string"
    }
  ],
  "scanned": 1,
  "underPaid": 1,
  "unresolved": 1
}

Fields

FieldTypeDescription
amountMismatchedintegerA transfer exists but nets a different amount — needs a human
confirmedSentinteger
dryRunboolean
rowsarray of object
rows[].amountintegerThe SETTLED amount, in CENTS
rows[].currencystring
rows[].errorstring
rows[].offsetForClawbackIdstring | nullThe clawback an offset payout collected for; null for a payout. A NO_TRANSFER_FOUND offset is released with POST /api/finance/clawbacks/{id}/offsets/{transactionId}/release.
rows[].orgIdstring
rows[].orgNamestring | null
rows[].outcome"CONFIRMED_SENT" | "NO_TRANSFER_FOUND" | "AMOUNT_MISMATCH" | "UNRESOLVED"
rows[].previousStatestring
rows[].stripeAmountintegerStripe's un-reversed transfer amount, in CENTS
rows[].stripeDestinationstring
rows[].stripeTransferIdstring
rows[].transactionIdstring
scannedinteger
underPaidintegerSettlements Stripe has no money movement for — needs a human
unresolvedinteger

When it fails

A failed call returns isError: true with the API's message as text. A change the person declines, or lets time out, also comes back this way and nothing changes.

400

limit, minAgeSeconds or dryRun is not of the declared type

403

Not platform staff

What the model is shown

This is the tool exactly as the server lists it in tools/list. The description starts with the REST call it makes.

json
{
  "name": "post_finance_payouts_reconcile",
  "description": "POST /api/finance/payouts/reconcile — For every settled payout still PENDING or FAILED, asks Stripe whether the transfer actually happened and promotes confirmed rows to SENT. Never creates a transfer and never writes FAILED. Defaults to a dry run — pass `dryRun: false` to commit the promotions.\n\nThis changes data. The person is asked to confirm it before it runs, and nothing happens if they decline.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "body": {
        "type": "string",
        "description": "The JSON request body: { dryRun: boolean (Ask Stripe and report, but write nothing); limit: integer (Max settlements to examine in one pass (DAL default 100)); minAgeSeconds: integer (Ignore settlements younger than this (default 900)) }"
      }
    }
  },
  "annotations": {
    "readOnlyHint": false,
    "destructiveHint": true,
    "idempotentHint": false,
    "openWorldHint": false
  }
}