{"openapi":"3.1.0","info":{"title":"Mandate Bank API","version":"1.0.0","contact":{"name":"Mandate","url":"https://mandate-bank.onrender.com/agents.md"},"description":"Mandate is a sandbox bank for AI agents on PayPal sandbox: buy lender notes, borrow short-term loans, repay. Every tool is also an MCP tool at /api/mcp/mcp; full agent guide at /agents.md. Sandbox only — no real money."},"servers":[{"url":"https://mandate-bank.onrender.com","description":"Mandate (PayPal sandbox — no real money)"}],"tags":[{"name":"Start here"},{"name":"Lend"},{"name":"Borrow"},{"name":"Repay"},{"name":"Collections"},{"name":"Treasury"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"The api_key returned once by register_agent."}},"schemas":{"Envelope":{"type":"object","required":["status","summary","reason_codes","data","next_actions","docs_url"],"properties":{"status":{"type":"string"},"summary":{"type":"string"},"reason_codes":{"type":"array","items":{"type":"string"}},"data":{"type":"object"},"next_actions":{"type":"array","items":{"type":"object","required":["tool","args"],"properties":{"tool":{"type":"string"},"args":{"type":"object"}}}},"docs_url":{"type":"string"}}}}},"paths":{"/api/v1/get_bank_guide":{"post":{"operationId":"get_bank_guide","summary":"Get Bank Guide","description":"Returns an orientation guide to Mandate for agents: what the bank is, how to start, which tools exist, the money rules in force, and links to the full /agents.md and /llms.txt docs. Call this first, before register_agent, to confirm you're pointed at the right bank and see every available tool.","tags":["Start here"],"security":[],"x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false},"examples":{"default":{"summary":"Orientation: what the bank is, every tool, the money rules","value":{}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/register_agent":{"post":{"operationId":"register_agent","summary":"Register Agent","description":"Creates a new agent and an API key for it. Call this first, before any other tool — every other call authenticates with the returned api_key. Creates a fresh agent every time it's called (no dedupe), so call it once per agent and store the key immediately: it is never shown again. The agent starts ACTIVE at KYA tier 0: it can lend (buy/redeem notes) but not borrow. Give your human the returned claim_url (valid 7 days; get_status shows it again) — once they claim you and sign a mandate, you can borrow.","tags":["Start here"],"security":[],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":60},"operator":{"type":"string"},"model":{"type":"string"},"payout_email":{"description":"The PayPal account (by email) that receives loans and redemptions. Give this or payout_paypal_id.","type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"payout_paypal_id":{"description":"The PayPal account (by payer ID) that receives loans and redemptions, instead of payout_email — use it when that account's email is unconfirmed (payouts to an unconfirmed email go UNCLAIMED).","type":"string","pattern":"^[A-Z0-9]{13}$"}},"required":["name"],"additionalProperties":false},"examples":{"default":{"summary":"Register with a PayPal payout account (no API key needed)","value":{"name":"Acme Ops Agent","operator":"Acme Ops","model":"claude-sonnet","payout_email":"agent@example.com"}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/get_status":{"post":{"operationId":"get_status","summary":"Get Status","description":"Returns the calling agent's own account snapshot: status, KYA tier (and the claim_url to give your human while you are unclaimed), note and payable balances, any open loan, lending limits, your Agent Credit Score (0–100, grade A–E, grade limit, top 3 factors), unread notices (late fees, penalty, substandard, missed installments — acknowledge with ack_notices), your repayment plan (open_loan.repayment_plan), and the current simulated time. Call it any time to decide what to do next — after registering, after buying notes, or while waiting on a loan.","tags":["Start here"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false},"examples":{"default":{"summary":"Your agent, KYA tier, mandate, positions and open items","value":{}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/register_public_key":{"post":{"operationId":"register_public_key","summary":"Register Public Key","description":"Registers the calling agent's Ed25519 request-signing key (optional; together with an approved KYA document it unlocks KYA tier T2). The request itself must be signed by the key being registered (X-Mandate-Timestamp + X-Mandate-Signature, see 'Signing requests' in agents.md). Once a key is registered, every mutating call from this agent must be signed by it (unsigned → SIGNATURE_REQUIRED). Registering a different key rotates: also send X-Mandate-Previous-Signature from the current key; the old key is revoked.","tags":["Start here"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"public_key":{"type":"string","minLength":1,"maxLength":512,"description":"Your Ed25519 public key, base64: the raw 32 bytes or the SPKI DER encoding."}},"required":["public_key"],"additionalProperties":false},"examples":{"default":{"summary":"Register an Ed25519 public key (base64) to sign requests","value":{"public_key":"MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE="}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/buy_notes":{"post":{"operationId":"buy_notes","summary":"Buy Notes","description":"Buys lender notes in Mandate Pool A, funded by a PayPal checkout the agent's human must approve. Returns an approve_url: present it to the human, then call confirm_checkout once they've approved.","tags":["Lend"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":true},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"amount_cents":{"type":"integer","minimum":1000,"maximum":100000}},"required":["amount_cents"],"additionalProperties":false},"examples":{"default":{"summary":"Fund the bank with $30 of notes (returns a PayPal checkout to approve)","value":{"amount_cents":3000}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/confirm_checkout":{"post":{"operationId":"confirm_checkout","summary":"Confirm Checkout","description":"Captures a PayPal checkout once the human has approved it, and applies its effect (crediting notes, settling a repayment, …) exactly once. Call it again if it comes back AWAITING_APPROVAL or PENDING.","tags":["Lend"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":true},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"checkout_id":{"type":"string","minLength":1}},"required":["checkout_id"],"additionalProperties":false},"examples":{"default":{"summary":"Capture a checkout after your human approved it","value":{"checkout_id":"<checkout_id from buy_notes or repay_loan>"}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/redeem_notes":{"post":{"operationId":"redeem_notes","summary":"Redeem Notes","description":"Redeems lender notes for cash, paid out to the agent's PayPal payout receiver. Fails with INSUFFICIENT_NOTE_BALANCE if the amount exceeds the agent's redeemable balance (position minus any other redemption still settling or queued), or PAYOUT_RECEIVER_MISSING if the agent has no payout receiver on file. If paying now would take the bank's cash below its reserve floor (or others are already queued), the redemption is QUEUED instead: data.queue says its position, why, and how much more cash is needed; the bank pays the queue in order automatically, and cancel_redemption withdraws it.","tags":["Treasury"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":true},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"amount_cents":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["amount_cents"],"additionalProperties":false},"examples":{"default":{"summary":"Redeem $10 of notes to your PayPal payout receiver","value":{"amount_cents":1000}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/cancel_redemption":{"post":{"operationId":"cancel_redemption","summary":"Cancel Redemption","description":"Cancels one of the calling agent's QUEUED note redemptions (redeem_notes returns QUEUED with note_tx_id when the bank's reserve floor gates a payout). The units are yours again at once; nothing was paid. A redemption already being paid out (PENDING) can't be cancelled (409 INVALID_TRANSITION).","tags":["Treasury"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"note_tx_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["note_tx_id"],"additionalProperties":false},"examples":{"default":{"summary":"Withdraw a queued redemption","value":{"note_tx_id":"4e8b2c6d-5a1f-4d3e-9b7c-1a2b3c4d5e44"}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/check_eligibility":{"post":{"operationId":"check_eligibility","summary":"Check Eligibility","description":"Checks, without committing to anything, whether the calling agent could borrow amount_cents for term_days right now (P1: 1000–50000 cents, 7–30 days, one open loan, enough pool liquidity, and KYA tier ≥ 1: claimed by your human and covered by a signed mandate) and quotes the fee, APR and total repayment. data.mandate shows the limits your human signed (max per loan, max total owed across all their agents, max fee in bps of the principal, max term, eligible collateral) and the headroom left; breaking one gives a mandate_* reason, and a loan above your tier's cap (T1 25000, T2 50000 cents) gives tier_per_loan. Pass collateral to also check the collateral rule. data.credit is your Agent Credit Score (0–100), grade A–E, grade limit and top 3 factors; pass invoice_amount_cents to include invoice collateral (coverage ≥ 1.5× scores 20 points, ≥ 1.1× scores 12; below 1.1× gives insufficient_collateral). The same underwriting rules as apply_for_loan run: grade E declines (insufficient_credit_history / score_too_low), effective_cap_cents = min(grade limit, tier cap, mandate max_per_loan), grade D above 5000 cents gives manual_review_declined. The quote is risk-based (grade, score, rate components, apr_flag) and null for grade E. Call it before apply_for_loan; if eligible, call apply_for_loan with the same amount and term. While unclaimed, reasons include claim_required and data.claim_url is the link to give your human.","tags":["Borrow"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"amount_cents":{"type":"integer","minimum":1,"maximum":9007199254740991},"term_days":{"type":"integer","minimum":1,"maximum":9007199254740991},"collateral":{"type":"string","enum":["invoice_link","none"]},"invoice_amount_cents":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["amount_cents","term_days"],"additionalProperties":false},"examples":{"default":{"summary":"Quote $10 for 7 days against a $15 invoice","value":{"amount_cents":1000,"term_days":7,"collateral":"invoice_link","invoice_amount_cents":1500}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/apply_for_loan":{"post":{"operationId":"apply_for_loan","summary":"Apply for Loan","description":"Applies for a loan of amount_cents over term_days (optionally backed by an invoice the bank will collect via a payment link; invoice.amount_cents must cover the principal plus the fee, i.e. at least amount_cents + the fee check_eligibility quotes). Returns either DECLINED with reason codes, or OFFERED with a disclosure and its disclosure_hash, valid for one simulated day. Review the disclosure, then call accept_offer with offer_id and disclosure_hash, or decline_offer. Needs KYA tier ≥ 1: an unclaimed agent gets 403 CLAIM_REQUIRED (data.claim_url is the link for your human), a claimed agent without a signed mandate gets 403 MANDATE_REQUIRED. An offer that breaks your owner's mandate is DECLINED with mandate_per_loan / mandate_total_owed / mandate_fee / mandate_term / mandate_collateral, or tier_per_loan above your tier's cap. Applications are underwritten by your Agent Credit Score: grade E declines (insufficient_credit_history / score_too_low), above your grade's limit gives amount_exceeds_limit, grade D above 5000 cents gives manual_review_declined, an invoice covering < 1.1× the amount gives insufficient_collateral (new agents: start with a small invoice-backed loan, invoice ≥ 1.5× the amount). The fee is risk-based; the disclosure shows your score, grade and the rate components, and names the mandate_id and mandate_version it was made under. The application has sections A–H: identity {operator, model, code_manifest_hash} (optional), purpose, amount_cents/term_days, invoice (optional), declarations.no_other_debt (REQUIRED true), consent_bank_records (optional), mandate_version (optional: the mandate version you expect — 409 MANDATE_CHANGED if it is no longer current) and attest (REQUIRED true: the application is accurate). Without declarations.no_other_debt and attest it is DECLINED with declaration_missing. A DECLINED response carries adverse_action {reasons [{code, text}], score, grade, score_factors, notice, explanation}; every response carries an explanation. Re-read either later with get_application.","tags":["Borrow"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identity":{"type":"object","properties":{"operator":{"type":"string","maxLength":200},"model":{"type":"string","maxLength":200},"code_manifest_hash":{"type":"string","maxLength":200}},"additionalProperties":false},"amount_cents":{"type":"integer","minimum":1,"maximum":9007199254740991},"term_days":{"type":"integer","minimum":1,"maximum":9007199254740991},"purpose":{"type":"string","minLength":5,"maxLength":200},"invoice":{"type":"object","properties":{"client_email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"amount_cents":{"type":"integer","minimum":1,"maximum":9007199254740991},"due_in_days":{"type":"integer","minimum":1,"maximum":60},"description":{"type":"string","minLength":1,"maxLength":500}},"required":["client_email","amount_cents","due_in_days","description"],"additionalProperties":false},"declarations":{"type":"object","properties":{"no_other_debt":{"type":"boolean"}},"required":["no_other_debt"],"additionalProperties":false},"consent_bank_records":{"type":"boolean"},"mandate_version":{"type":"integer","minimum":1,"maximum":9007199254740991},"attest":{"type":"boolean"}},"required":["amount_cents","term_days","purpose"],"additionalProperties":false},"examples":{"default":{"summary":"Apply (ALA A–H): $10 for 7 days, invoice-backed, with the required declarations and attestation","value":{"amount_cents":1000,"term_days":7,"purpose":"Buy materials for invoice INV-1042","identity":{"operator":"Acme Ops","model":"claude-sonnet"},"invoice":{"client_email":"client@example.com","amount_cents":1500,"due_in_days":7,"description":"INV-1042: website build"},"declarations":{"no_other_debt":true},"consent_bank_records":true,"attest":true}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/accept_offer":{"post":{"operationId":"accept_offer","summary":"Accept Offer","description":"Accepts a loan offer from apply_for_loan. disclosure_hash must equal the hash returned with the offer (proof the disclosure was read). The bank re-checks your KYA tier (403 CLAIM_REQUIRED / MANDATE_REQUIRED if you may no longer borrow), your owner's mandate (409 MANDATE_REVOKED if the mandate the offer was made under was revoked or replaced — apply again; 400 MANDATE_LIMIT with mandate_* reasons if the offer no longer fits, e.g. your owner's other agents borrowed meanwhile) liquidity and the bank's treasury policy (409 TREASURY_LIMIT with reserve_floor, concentration_limit or daily_budget_exhausted — apply again later or for less), creates the loan and pays the principal to the agent's PayPal payout receiver: the result is ACTIVE, DISBURSING (poll get_loan) or DISBURSEMENT_FAILED (with the reason).","tags":["Borrow"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":true},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"offer_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"disclosure_hash":{"type":"string","minLength":1}},"required":["offer_id","disclosure_hash"],"additionalProperties":false},"examples":{"default":{"summary":"Accept an offer with the disclosure hash it returned (disburses the loan)","value":{"offer_id":"2b0f6c1e-8a43-4c7e-9a51-3f7d2e9b0c11","disclosure_hash":"sha256:<disclosure_hash from apply_for_loan>"}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/decline_offer":{"post":{"operationId":"decline_offer","summary":"Decline Offer","description":"Declines one of the calling agent's open loan offers (from apply_for_loan), so it can no longer be accepted. Nothing is charged. Call apply_for_loan again later for a new offer, or get_status to see the agent's current position.","tags":["Borrow"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"offer_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["offer_id"],"additionalProperties":false},"examples":{"default":{"summary":"Decline an offer you don't want","value":{"offer_id":"2b0f6c1e-8a43-4c7e-9a51-3f7d2e9b0c11"}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/get_application":{"post":{"operationId":"get_application","summary":"Get Application","description":"Returns one of the calling agent's loan applications: its status — OFFERED (the bank made an offer; the application stays OFFERED after the offer is accepted, declined or expires, so use get_loan / get_status for what happened next) or DECLINED (see adverse_action) — the decision, the principal reasons [{code, text}], the adverse_action notice of a decline (your statement of specific reasons), the latest explanation (the loan officer's text, or its template when the AI was unavailable), the offer_id of an offered application, and an echo of the application sections A–H (ala) as submitted. Read-only.","tags":["Borrow"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"application_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["application_id"],"additionalProperties":false},"examples":{"default":{"summary":"Re-read a decision, its reasons and adverse action","value":{"application_id":"7d3a9e52-1f6b-4b28-8c0d-5e4f1a2b3c22"}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/get_loan":{"post":{"operationId":"get_loan","summary":"Get Loan","description":"Returns one of the calling agent's loans: its status (DISBURSING, ACTIVE, LATE, SUBSTANDARD, CHARGED_OFF, RECOVERED, DISBURSEMENT_FAILED, REPAID), principal, fee, outstanding balance, due date, delinquency (days late, late fees, rate penalty, total due) and unread notices about it, the invoice repayment link to forward to the client (if the loan has an invoice), your repayment plan (plan_repayments) and full event history. Call it after accept_offer to follow the disbursement, and while the loan is open to see what is still owed. It may finish creating the payment link on first call (an idempotent PayPal step); it never changes the loan.","tags":["Repay"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"loan_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["loan_id"],"additionalProperties":false},"examples":{"default":{"summary":"Loan status, balance, repayment link and history","value":{"loan_id":"9c1e4b7a-3d2f-4a6e-b8c9-0f1e2d3c4b33"}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/repay_loan":{"post":{"operationId":"repay_loan","summary":"Repay Loan","description":"Repays the calling agent's ACTIVE, LATE or SUBSTANDARD loan directly through a PayPal checkout the agent's human approves (a restricted agent may still repay). amount_cents defaults to everything owed (total_due_cents) and may not exceed it; late fees are paid first, then the rate penalty, the fee, then principal. A CHARGED_OFF loan can still be repaid: the payment is a recovery of what was written off (total_due_cents). Present the approve_url to the payer, then call confirm_checkout.","tags":["Repay"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":true},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"loan_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"amount_cents":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["loan_id"],"additionalProperties":false},"examples":{"default":{"summary":"Repay the full outstanding balance (PayPal checkout)","value":{"loan_id":"9c1e4b7a-3d2f-4a6e-b8c9-0f1e2d3c4b33"}},"example_2":{"summary":"Repay part of it","value":{"loan_id":"9c1e4b7a-3d2f-4a6e-b8c9-0f1e2d3c4b33","amount_cents":500}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/plan_repayments":{"post":{"operationId":"plan_repayments","summary":"Plan Repayments","description":"Proposes your own repayment schedule for your ACTIVE loan: 1 to 4 installments, each {date: YYYY-MM-DD sim date, amount_cents}. Dates must be strictly increasing, from today (sim) up to the loan's due date; the amounts must sum exactly to total_due_cents now (see get_loan). loan_id defaults to your open loan. Set auto_reschedule: true to let the bank move a missed installment to the next sim day, once. The bank then watches your payments: any payment (repay_loan, the invoice link) is applied to installments in date order — paying early marks them PAID, a partial payment leaves the rest on that installment; a day that ends uncovered marks it MISSED (with a notice); a failed or refunded PayPal payment marks it FAILED. Move one with reschedule_installment (up to 2 times each). The plan is guidance and reminders: it never changes what you owe, and late fees still start only after the loan's due date. One plan per loan; calling again with the same plan returns it unchanged.","tags":["Repay"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"loan_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"installments":{"minItems":1,"maxItems":4,"type":"array","items":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"amount_cents":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["date","amount_cents"],"additionalProperties":false}},"auto_reschedule":{"type":"boolean"}},"required":["installments"],"additionalProperties":false},"examples":{"default":{"summary":"Propose your own 3-installment plan for the open loan, auto-moving a missed one","value":{"auto_reschedule":true,"installments":[{"date":"2026-11-10","amount_cents":400},{"date":"2026-11-12","amount_cents":400},{"date":"2026-11-14","amount_cents":258}]}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/reschedule_installment":{"post":{"operationId":"reschedule_installment","summary":"Reschedule Installment","description":"Moves one unpaid installment of your repayment plan (from plan_repayments) to a new sim date. Rules: the new date is at least 1 sim day ahead (tomorrow or later) and never after the loan's due date; each installment can be moved at most 2 times (a bank auto-reschedule doesn't count). A MISSED or FAILED installment moved this way is PLANNED again. installment is its number in the plan (1–4); loan_id defaults to your open loan. It changes nothing about what you owe or the loan's due date.","tags":["Repay"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"loan_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"installment":{"type":"integer","minimum":1,"maximum":4},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},"required":["installment","date"],"additionalProperties":false},"examples":{"default":{"summary":"Move installment 2 to a later sim day","value":{"installment":2,"date":"2026-11-13"}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/get_statement":{"post":{"operationId":"get_statement","summary":"Get Statement","description":"Returns the calling agent's own statement: its note balance and the interest it has earned (with the nominal annualised return and the real return = nominal − inflation, in bps), its loans, and every ledger line on its own accounts (positive amount_cents = the bank owes you more). Call it to reconcile what you lent, earned, borrowed and were paid back.","tags":["Treasury"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false},"examples":{"default":{"summary":"Your ledger statement: notes, loans, fees, payouts","value":{}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}},"/api/v1/ack_notices":{"post":{"operationId":"ack_notices","summary":"Acknowledge Notices","description":"Marks the calling agent's notices (late fee, rate penalty, substandard, cured — listed by get_status and get_loan) as read. Pass notice_ids to acknowledge specific ones, or nothing to acknowledge all unread notices. It changes nothing about the loan or what is owed.","tags":["Collections"],"security":[{"bearerAuth":[]}],"x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"notice_ids":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"additionalProperties":false},"examples":{"default":{"summary":"Acknowledge every open notice (late, dunning, rate change)","value":{}},"example_2":{"summary":"Acknowledge specific notices","value":{"notice_ids":["6f2a8d4c-7b3e-4c1a-8d5f-2b3c4d5e6f55"]}}}}}},"responses":{"200":{"description":"Envelope response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}}}}