API reference

You call Moov to register users and mint sender tokens. Moov calls you to hold, capture, and credit money on your core.

You call Moov at https://api.moov.money (API key, HTTP Basic): participants, funding sources, sender tokens, reviews, providers, and limits.

Payouts are not included on the list. The SDK creates them on the device against the sender’s own session, using a token you mint. There is no provider-callable payout endpoint. See sender authentication.

Moov calls you for holds and credits. You register URLs. Moov POSTs to them as-is. The /ledger/* paths below are labels only.

URLCalled whenShape
AuthorizationURLA user initiates a paymentAuthorize
CaptureURLThe recipient completes a claimCapture
HoldReleaseURLA payment is canceled or expiresRelease
CreditURLA request has been paid into your walletCredit account

Ledger request and response bodies are encrypted JWEs. Inner JWT: iat and exp at the top; Moov fields under moov. See setup to register URLs.

Versioning #

The API is versioned by date. Send the version you built against on every request:

X-Moov-Version: v2026.10.00

Everything in this reference is the v2026.10.00 surface. If you omit the header, the server applies its default, which can be an older version with different paths and shapes, so always pin a version. Versions are vYYYY.QQ.BB (year, quarter’s starting month, build). Breaking changes only ship as a new dated version, and your pinned version keeps its behavior. The ledger endpoints you host are unaffected: Moov calls them, and the envelope carries its own contract.

Conventions #

Every call you make to api.moov.money follows the same rules:

AuthHTTP Basic with your API key: -u "$MOOV_API_KEY_ID:$MOOV_API_KEY_SECRET"
VersionX-Moov-Version: v2026.10.00 on every request
CreatesParticipants and signing secrets require X-Idempotency-Key (1–255 characters). Reuse the key on a retry; it is held for 24 hours
Participant paths{participantID} takes Moov’s participantID (ends in _user) or your externalID
ListsPass limit (1–100, default 25) and cursor. Follow nextCursor while hasMore is true
ErrorsBodies are RFC 9457 problem details. Branch on type; 400 is a malformed request, 422 a body that failed validation, with each field under errors. 401, 403, and 404 have no body. A stale expectedVersionID on a limit edit returns 409 with type …#version-conflict and the latest currentVersion; re-read and retry