For the complete documentation index, see llms.txt. This page is also available as Markdown.

API Reference

Full endpoint documentation

Base URL: https://business.madhousewallet.com Authentication: Authorization: Bearer mw_live_<keyId>_<secret> Content-Type: application/json

Interactive API docs are available at https://developer.madhousewallet.com.

All successful responses are returned as JSON. Rate limits are per API key.


MCP Server

Endpoint: https://mcp.madhousewallet.com/

Madhouse Wallet offers a hosted Model Context Protocol (MCP) server that exposes the payouts API as a set of tools your AI agents can call directly. Instead of hand-wiring HTTP requests, an MCP-compatible client (Claude, Cursor, or any agent framework) can discover and invoke wallet actions — fetching quotes, managing recipients, and initiating transfers — through a single connection.

Use it to let AI agents:

  • Look up account requirements and create recipients

  • Request locked FX quotes

  • Initiate and track USDC off-ramp transfers

  • Programmatically orchestrate payouts as part of an agentic workflow

Authentication uses the same mw_live_<keyId>_<secret> API keys described above.

For setup instructions, the full tool catalog, and client configuration, see https://mcp.madhousewallet.com/.


Recipients

GET /api/payouts/recipients

List all recipients for the authenticated account.

Rate limit: 30 req/min

Response:


POST /api/payouts/recipients

Create a new payout recipient.

Rate limit: 30 req/min

Request body:

Use GET /api/payouts/account-requirements first to determine the correct type and required details fields for each currency.

Response:


GET /api/payouts/recipients/:id

Fetch a single recipient by ID.

Rate limit: 30 req/min


DELETE /api/payouts/recipients/:id

Delete a recipient. Returns 409 Conflict if a transfer for this recipient is in a non-terminal status.

Rate limit: 30 req/min


Account Requirements

GET /api/payouts/account-requirements

Fetch required fields for creating a recipient in a target currency.

Rate limit: 60 req/min

Query parameters:

Parameter
Type
Description

source

string

Source currency (e.g. USD)

target

string

Target fiat currency (e.g. KES)

sourceAmount

number

Amount in source currency

Response (array of requirement types):

Fields with refreshRequirementsOnChange: true (e.g. legalType) require a follow-up POST to this endpoint with the current form state to receive updated field lists.


POST /api/payouts/account-requirements

Refresh requirements after a refreshRequirementsOnChange field changes.

Rate limit: 60 req/min

Request body:


Quotes

GET /api/payouts/quote

Get a locked FX quote. Valid for 5 minutes.

Rate limit: 20 req/min

Query parameters:

Parameter
Type
Description

targetCurrency

string

Target fiat currency (e.g. KES)

sourceAmount

number

USD amount to send

Response:

Pass quoteId to POST /api/payouts/transfer within the 5-minute window.


Transfers

POST /api/payouts/transfer

Initiate a USDC off-ramp transfer.

Rate limit: 5 req/min

Request body:

Field
Type
Required
Description

quote_id

string

Yes

From GET /api/payouts/quote

source_wallet

string

Yes

Ethereum address (0x...) sending the USDC

amount

number

Yes

USD amount (must match quote ±$0.01)

recipientId

number

Yes

From POST /api/payouts/recipients

customer_uuid

string

No

Your own idempotency key (prevents duplicates on retry)

Response:

Send exactly amount USDC from source_wallet to escrow_wallet before expires_at.

Error codes:

Code
Meaning

400

Invalid input or stale/mismatched quote

403

Recipient not owned by this account

409

Duplicate customer_uuid

429

Rate limit exceeded


POST /api/payouts/transfer/cancel

Cancel a transfer before USDC has been sent.

Rate limit: 20 req/min

Request body:

Returns 409 if the transfer has already received a deposit.


GET /api/payouts/transfer/:id

Get transfer status from the database snapshot.

Rate limit: 30 req/min


GET /api/payouts/transfer-status/:id

Get transfer status with live quote data and recipient details fetched in real time.

Rate limit: 30 req/min

Response:


Rate Limits

Rate limits are per API key. Headers are included on every response:

When exceeded, the API returns 429 Too Many Requests. Back off and retry after X-RateLimit-Reset.


Errors

All errors follow the format:

Status
Meaning

400

Bad request — check input parameters

401

Invalid or missing API key

403

Forbidden — resource not owned by this account

404

Resource not found

409

Conflict — duplicate or in-flight transfer

429

Rate limit exceeded

500

Internal server error — contact support

Last updated

Was this helpful?