Authorize

POST
/ledger/authorize

The path above is illustrative. You host this endpoint; Moov Money POSTs to the URL you register for this operation. See Setup.

Authorize a payout and place a hold on the sender’s funding source.

The request body is a RequestEnvelope; the inner JWE payload conforms to AuthorizeRequestJWTPayload. The response body is a ResponseEnvelope; the inner JWE payload conforms to AuthorizeResponseJWTPayload.

Outcomes (200 OK):

  • approved: hold placed.
  • denied: you declined (insufficient funds, fraud, step-up required, etc.). No hold placed.

For processing failures (ledger unavailable, transient errors), return a retryable HTTP status: 408, 429, or a 5xx. Do not return 200 with an unmodeled outcome value; Moov Money will treat that as an internal unknown result and discard the FI-supplied reason.

Idempotency: you must return the same outcome (and same holdReference if approved) for repeated requests with the same idempotencyKey. The scope of an authorize idempotencyKey is Moov Money’s payout, so the same key will not be reused for a different payout.

Retries: Moov Money will retry on 408, 429, 5xx, and transport errors. Return other 4xx for terminal validation failures (bad JWE, unknown provider, malformed claims).

Request
cURL
curl -X POST https://fi.example.com/ledger/authorize \
  -H "Content-Type: application/json" \
  -d '{
  "request": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIiwiY3R5IjoiSldUIn0.…"
}'
Responses
200
The request has succeeded.
{
  "response": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIiwiY3R5IjoiSldUIn0.…"
}

Request

application/json
Every FI ledger endpoint accepts the same envelope: a single JWE string in the request field. All business fields (amounts, references, idempotency key) travel inside the JWE claims, not in the outer JSON.

request

string required
Compact-serialized JWE carrying the request claims.

Request claims

Inner JWT
Full JWT payload of the request JWE for POST authorize.

exp

integer<int64> required
Expiration time (JWT NumericDate, Unix seconds).

moov

object required
Moov-namespaced claims for the operation.
Moov claims

moov

payoutID

string required
Moov payout ID this call relates to.

providerID

string required
Moov account ID identifying you as the provider being called.

externalID

string required
Your own identifier for the sender participant. Lets you resolve the payout to the user it already knows about without needing Moov’s participant IDs.

fundingSource

string required
Provider-issued token identifying where the money is coming from (card token, bank-account token, wallet ID, etc.). Opaque to Moov.

amount

object required
Amount to authorize (i.e. the size of the hold to place).
Show child attributes

moov.amount

currency

object required
ISO 4217 currency descriptor.
Show child attributes

moov.amount.currency

decimalPlaces

integer<uint8> required
Number of minor-unit decimal places for code. Required.

numericCode

string
ISO 4217 numeric currency code, if known. Informational only.

name

string
Human-readable currency name, if known. Informational only.

code

string required
Uppercase 3-letter ISO 4217 currency code.

value

string required
Decimal amount as a string.

fraudScore

number<float> required
Fraud score from the fraud check, 0.0 to 1.0. Higher means riskier. You can factor this into your decision (e.g. require step-up auth above a threshold).

callerSubject

string
Subject of the Moov caller. Audit-only.

requestID

string
Moov request ID for correlation. Audit-only.

idempotencyKey

string required
Moov-chosen idempotency nonce. Echo it back on your response. The dedupe scope of this key is per endpoint: don’t treat an idempotencyKey you saw on authorize as already processed if it turns up on release or capture, and vice versa. Moov Money currently derives per-payout keys that may collide across the three endpoints; treating them as endpoint-scoped is required for correctness.

typ

string<enum> required
Request type. Always authorize on this operation.
Possible values: authorize

iat

integer<int64> required
Issued-at time (JWT NumericDate, Unix seconds).

Response claims

Inner JWT
Full JWT payload of the response JWE for POST authorize.

exp

integer<int64> required
Expiration time (JWT NumericDate, Unix seconds).

moov

object required
Moov-namespaced claims for the operation.
Moov claims

moov

reason

string
Human-readable reason. Required for denied/failed; optional for approved.

outcome

string<enum> required

High-level decision.

  • approved: you have placed a hold. holdReference is required.
  • denied: you have refused this authorization (insufficient funds, fraud rules, step-up required, etc.). No hold placed.

If you cannot process the request (e.g. downstream ledger unavailable), it should return a retryable HTTP status (408, 429, 5xx) rather than a 200 with a non-approved outcome. Moov Money treats any authorize outcome other than approved or denied as an internal unknown result and does not propagate FI-supplied reasons for it. Do not use a 200 with an unmodeled outcome to communicate processing failure.

Possible values: approved, denied

holdReference

string
FI-issued reference for the resulting hold. Required when outcome=approved; must be supplied by Moov on later release and capture calls for the same payout. Omit when outcome=denied.

idempotencyKey

string required
Echoed from the request. Moov rejects the response if this does not match.

iat

integer<int64> required
Issued-at time (JWT NumericDate, Unix seconds).

Response

Every FI ledger endpoint returns the same envelope: a single JWE string in the response field. All business fields (outcome, references, echoed idempotency key) travel inside the JWE claims, not in the outer JSON.

response

string required
Compact-serialized JWE carrying the response claims.