post_finance_clawbacks

Changes data · you confirm first

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

File a payout clawback — a clinic for a voucher it took, or platform staff

Asks that a service provider return some or all of a PAID voucher's payout, for Pawsitive Future to decide. Records the request and moves no money; the voucher stays PAID. A clinic files only for a voucher it took, holding execute:CreateClawbackRequestCommand in that clinic, and only with PROCEDURE_NOT_COMPLETED, BENEFICIARY_DISPUTE or OTHER; platform staff file with any reason, on Pawsitive Future's behalf. The org is read off the voucher, never the body. A voucher that is absent, or that the caller's clinic did not take, is answered 404 alike. The amount is more than 0 and at most what is left of the voucher's payout — its credited amount less every other clawback of it that was not denied (400, in words); OTHER needs a memo of at least 20 characters; a voucher carries one clawback in flight at a time (409). Answered as the clinic reads it.

Arguments

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

Fields of body

FieldTypeDescription
amountintegerrequiredCENTS asked back.
feeLiabilityobject | nullPlatform staff only: who bears the processing cost, proposed for the approval. A service provider naming one is refused 403.
memostring | null
reasonCode"PFF_DISCRETIONARY" | "PROCEDURE_NOT_COMPLETED" | "BENEFICIARY_DISPUTE" | "DUPLICATE_OR_ERRONEOUS_PAYOUT" | "DONATION_REVERSED" | "OTHER"requiredWhy a clawback was filed. A service provider files PROCEDURE_NOT_COMPLETED, BENEFICIARY_DISPUTE or OTHER about a payout it received; the rest are Pawsitive Future's findings. OTHER needs a memo of at least 20 characters.
voucherIdstring (uuid)required

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_clawbacks",
    "arguments": {
      "body": {
        "amount": 1,
        "reasonCode": "PFF_DISCRETIONARY",
        "voucherId": "11111111-1111-4111-8111-111111111111",
        "feeLiability": {},
        "memo": "string"
      }
    }
  }
}
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 201) the tool returns one text item holding the API's JSON, pretty-printed.

The clawback, REQUESTED, as its clinic reads it

json
{
  "amount": 1,
  "currency": "string",
  "decidedAt": 1,
  "filedBy": "SERVICE_PROVIDER",
  "id": "11111111-1111-4111-8111-111111111111",
  "memo": "string",
  "noticeSentAt": 1,
  "owedCents": 1,
  "reasonCode": "PFF_DISCRETIONARY",
  "repayment": {
    "processing": {
      "amountCents": 1,
      "since": 1
    },
    "processingFee": {
      "card": {},
      "us_bank_account": {}
    },
    "repayableCents": 1
  },
  "requestedAt": 1,
  "status": "REQUESTED",
  "voucherCode": "string",
  "voucherId": "11111111-1111-4111-8111-111111111111"
}

Fields

FieldTypeDescription
amountintegerCENTS asked back.
currencystring
decidedAtinteger | nullEpoch milliseconds Pawsitive Future approved or denied it; null while it awaits a decision.
filedBy"SERVICE_PROVIDER" | "PAWSITIVE_FUTURE"Who filed a clawback — the service provider that was paid, or Pawsitive Future staff.
idstring (uuid)
memostring | nullWhat the service provider wrote when it filed; null for a clawback Pawsitive Future filed.
noticeSentAtinteger | nullEpoch milliseconds the clinic was sent the written notice of an approved clawback; null before one was sent.
owedCentsintegerCENTS still owed while it is being collected; 0 otherwise.
reasonCode"PFF_DISCRETIONARY" | "PROCEDURE_NOT_COMPLETED" | "BENEFICIARY_DISPUTE" | "DUPLICATE_OR_ERRONEOUS_PAYOUT" | "DONATION_REVERSED" | "OTHER"Why a clawback was filed. A service provider files PROCEDURE_NOT_COMPLETED, BENEFICIARY_DISPUTE or OTHER about a payout it received; the rest are Pawsitive Future's findings. OTHER needs a memo of at least 20 characters.
repaymentobjectWhat the clinic may repay of one clawback from its Payout tab now. Repayable once the clawback is being collected (EXECUTING) and its payout transfer is reversed or needs none: what is owed, less offsets in flight, bank debits recorded or started at Stripe, and portal payments still settling. 0 otherwise.
repayment.processingobject | nullThe clinic's portal payments still settling (a bank payment takes days); null when none.
repayment.processing.amountCentsintegerCENTS they repay, fee excluded.
repayment.processing.sinceintegerEpoch milliseconds the oldest was made.
repayment.processingFeeobject | nullThe processor's rates the clinic pays on top, the fee shown as its own line before it pays; null when it pays none (Pawsitive Future absorbs it, or the Terms allowing it are not yet in effect).
repayment.processingFee.cardobject
repayment.processingFee.us_bank_accountobject
repayment.repayableCentsintegerCENTS the clinic may repay now, fee excluded.
requestedAtintegerEpoch milliseconds.
status"REQUESTED" | "APPROVED" | "DENIED" | "EXECUTING" | "RECOVERED" | "PARTIALLY_RECOVERED" | … (7 values)A payout clawback's lifecycle, kept apart from its ledger transaction's status. Filing and deciding reach REQUESTED, APPROVED and DENIED; the rest follow execution. RECOVERED is "cash confirmed": Pawsitive Future has confirmed the full amount is back in hand, never merely a booked reversal.
voucherCodestring
voucherIdstring (uuid)

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

The request was malformed or failed a guard.

403

The caller holds the permission in no org, or is a service provider naming a reason only Pawsitive Future files.

404

No such voucher, or not one the caller's clinic took.

409

The voucher is not PAID, or already has a clawback in flight. Carries the DAL's sentence.

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_clawbacks",
  "description": "POST /api/finance/clawbacks — Asks that a service provider return some or all of a PAID voucher's payout, for Pawsitive Future to decide. Records the request and moves no money; the voucher stays PAID. A clinic files only for a voucher it took, holding execute:CreateClawbackRequestCommand in that clinic, and only with PROCEDURE_NOT_COMPLETED, BENEFICIARY_DISPUTE or OTHER; platform staff file with any reason, on Pawsitive Future's behalf. The org is read off the voucher, never the body. A voucher that is absent, or that the caller's clinic did not take, is answered 404 alike. The amount is more than 0 and at most what is left of the voucher's payout — its credited amount less every other clawback of it that was not denied (400, in words); OTHER needs a memo of at least 20 characters; a voucher carries one clawback in flight at a time (409). Answered as the clinic reads it.\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: { amount*: integer (CENTS asked back.); feeLiability: {  } (Platform staff only: who bears the processing cost, proposed for the approval.); memo: string; reasonCode*: one of \"PFF_DISCRETIONARY\" | \"PROCEDURE_NOT_COMPLETED\" | \"BENEFICIARY_DISPUTE\" | \"DUPLICATE_OR_ERRONEOUS_PAYOUT\" | \"DONATION_REVERSED\" | \"OTHER\" (Why a clawback was filed.); voucherId*: string }"
      }
    },
    "required": [
      "body"
    ]
  },
  "annotations": {
    "readOnlyHint": false,
    "destructiveHint": true,
    "idempotentHint": false,
    "openWorldHint": false
  }
}