Individual Payout Limits
Overview
An individual customer starts with the corridor's default payout limits. Read them at any time, and ask for higher ones when the customer needs more headroom. A business customer has no equivalent flow.
GET /limits ──▶ collect risk profile + documents ──▶ POST /limit-requests ──▶ review ──▶ REVIEWED ──▶ GET /limits
The four steps
- Read the current limits — what the ceilings are now, and how much is left.
- Supply the risk profile — the customer's occupation, employment, and funding details.
- Upload the supporting documents — evidence of where the funds come from.
- Submit the request and track the review — the review completes asynchronously.
What to know before you start
- This applies to
INDIVIDUALcustomers only. ABUSINESScustomer gets400 VALIDATION_ERRORon a limit request, and an empty limits list. - The customer must already be onboarded and
ACTIVEat the corridor. Checkonboarding[].statusonGET /v1/payments/customers/{customer_id}first. - Only one request can be open at a time. Submitting again while one is under review returns the open request unchanged.
- A completed review reports the limits in effect afterwards, not an approve/decline decision. The limits can come back unchanged, so compare them against the read you took before requesting.
1. Read the current limits
GET /v1/payments/customers/{customer_id}/limits
curl https://api-staging.checker.finance/v1/payments/customers/cus_01ARZ3NDEKTSV4RRFFQ69G5KYC/limits \
-H "X-Api-Key: $API_KEY" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Nonce: $(uuidgen)" \
-H "X-Signature: $SIGNATURE"Response — 200 OK:
{
"data": [
{
"provider": "provider-a",
"limits": [
{
"type": "WITHDRAWAL",
"period": "DAILY",
"currency": "USD",
"limit": "10000.00",
"used": "250.00",
"remaining": "9750.00"
},
{
"type": "WITHDRAWAL",
"period": "ROLLING_30D",
"currency": "USD",
"limit": "50000.00",
"used": "250.00",
"remaining": "49750.00"
}
]
}
]
}| Field | Meaning |
|---|---|
type | The operation the limit constrains. |
period | The window the limit is measured over — DAILY or ROLLING_30D. |
limit | The ceiling for that window. |
used | Consumed so far in the current window. |
remaining | limit − used: the headroom a payout can use right now. |
Notes:
- An empty
dataarray means there is no limits-capable corridor for this customer yet — a business customer, or an individual still onboarding. - Add
?provider=provider-ato read one corridor. Unlike the default read, this is strict: an unknown identifier returns400 PROVIDER_NOT_AVAILABLE, and a corridor that does not review limits returns422 OPERATION_NOT_SUPPORTED. - An unknown
customer_idreturns404 NOT_FOUND.
2. Supply the risk profile
Higher limits need a fuller picture of the customer than onboarding collects. Send it as kyc.risk_profile, either on the customer record now or inline on the request in step 4.
PATCH /v1/payments/customers/{customer_id}
curl -X PATCH https://api-staging.checker.finance/v1/payments/customers/cus_01ARZ3NDEKTSV4RRFFQ69G5KYC \
-H "X-Api-Key: $API_KEY" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Nonce: $(uuidgen)" \
-H "X-Signature: $SIGNATURE" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"kyc": {
"risk_profile": {
"occupation": "SOFTWARE_DEVELOPER",
"employment_status": "EMPLOYED",
"source_of_funds": ["EMPLOYMENT_INCOME", "PERSONAL_SAVINGS"],
"purpose_of_account": ["SALARY_AND_INCOME_RECEIPT", "PERSONAL_EXPENSES"],
"anticipated_monthly_activity": "UNDER_100K"
}
}
}'All five fields are required. A partial profile is treated as no profile at all, so the request in step 4 returns 422 MISSING_KYC_FIELDS naming whichever are absent.
| Field | Values |
|---|---|
occupation | A closed list of occupation titles, e.g. SOFTWARE_DEVELOPER, ACCOUNTANT_AUDITOR, REGISTERED_NURSE, PHYSICIAN, LAWYER, UNIVERSITY_PROFESSOR, AIRCRAFT_PILOT, CARPENTER, SALES_REPRESENTATIVE, UNEMPLOYED_NO_WORK_5_YEARS. See the Occupation schema in the API reference for the full set. |
employment_status | EMPLOYED, SELF_EMPLOYED, RETIRED, STUDENT, UNEMPLOYED |
purpose_of_account | One or more of SALARY_AND_INCOME_RECEIPT, PERSONAL_EXPENSES, FAMILY_SUPPORT, BUSINESS_OPERATIONS, PURCHASE_GOODS_AND_SERVICES, RECEIVE_PAYMENTS_FOR_GOODS_AND_SERVICES, ECOMMERCE_PAYMENTS, INVESTMENT_PURPOSES, OTHER |
source_of_funds | One or more of EMPLOYMENT_INCOME, PERSONAL_SAVINGS, GOVERNMENT_BENEFITS, BUSINESS_INCOME, PENSION_RETIREMENT, INVESTMENT_PROCEEDS, SALE_OF_ASSETS, SALES_OF_GOODS_AND_SERVICES |
anticipated_monthly_activity | Expected monthly volume in USD: UNDER_100K, 100K_TO_1M, 1M_TO_10M, 10M_TO_50M, 50M_TO_250M, OVER_250M |
Notes:
- The profile holds no sensitive identifiers, so every field is returned on
GET /v1/payments/customers/{customer_id}. Re-PATCHit at any time to correct a value.
3. Upload the supporting documents
A limit review needs evidence of where the money comes from, and an address confirmation recent enough to support the higher ceiling. Upload each file separately.
POST /v1/payments/customers/{customer_id}/upload
curl -X POST https://api-staging.checker.finance/v1/payments/customers/cus_01ARZ3NDEKTSV4RRFFQ69G5KYC/upload \
-H "X-Api-Key: $API_KEY" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Nonce: $(uuidgen)" \
-H "X-Signature: $SIGNATURE" \
-F "file=@jane_payslips.pdf" \
-F "file_type=SOURCE_OF_FUNDS"Notes:
- Repeat the upload with
file_type=PROOF_OF_ADDRESS(for example a utility bill or bank statement). SOURCE_OF_FUNDSis accepted for individuals only; sending it for a business returns400 VALIDATION_ERROR.- A missing document comes back from step 4 as
422 MISSING_KYC_FIELDSwithfiles.SOURCE_OF_FUNDSorfiles.PROOF_OF_ADDRESSindetails.missing. - A proof of address already accepted during onboarding is reused, so a second request does not discard evidence that has already cleared review.
- Accepted formats are PDF, JPG, JPEG, and PNG, up to 10 MB each.
4. Submit the request and track the review
Submit the request
POST /v1/payments/customers/{customer_id}/limit-requests
curl -X POST https://api-staging.checker.finance/v1/payments/customers/cus_01ARZ3NDEKTSV4RRFFQ69G5KYC/limit-requests \
-H "X-Api-Key: $API_KEY" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Nonce: $(uuidgen)" \
-H "X-Signature: $SIGNATURE" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"provider": "provider-a"
}'Response — 202 Accepted:
{
"provider": "provider-a",
"status": "REQUESTED",
"requested_at": "2026-10-21T14:05:00Z"
}To skip step 2 and send the profile with the request, add it as profile:
{
"provider": "provider-a",
"profile": {
"occupation": "SOFTWARE_DEVELOPER",
"employment_status": "EMPLOYED",
"source_of_funds": ["EMPLOYMENT_INCOME", "PERSONAL_SAVINGS"],
"purpose_of_account": ["SALARY_AND_INCOME_RECEIPT", "PERSONAL_EXPENSES"],
"anticipated_monthly_activity": "UNDER_100K"
}
}The profile is stored on the customer before the request is submitted, so the two routes end in the same state. Omit profile to use whatever is already on the customer.
Notes:
- Submitting again while a request is still
REQUESTEDreturns200 OKwith that open request and starts no second review. - A customer not yet
ACTIVEat the corridor returns400 CUSTOMER_INACTIVE. PollGET /v1/payments/customers/{customer_id}and retry once the corridor reportsACTIVE. - A
BUSINESScustomer returns400 VALIDATION_ERROR; a corridor that does not review limits returns422 OPERATION_NOT_SUPPORTED. - An incomplete profile or a missing document returns
422 MISSING_KYC_FIELDSwithdetails.missingnaming every gap at once, e.g.["kyc.risk_profile.occupation", "files.SOURCE_OF_FUNDS"]. Fill them and retry.
Track the review
GET /v1/payments/customers/{customer_id}/limit-requests
curl https://api-staging.checker.finance/v1/payments/customers/cus_01ARZ3NDEKTSV4RRFFQ69G5KYC/limit-requests \
-H "X-Api-Key: $API_KEY" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Nonce: $(uuidgen)" \
-H "X-Signature: $SIGNATURE"Response — 200 OK:
{
"data": [
{
"provider": "provider-a",
"status": "REVIEWED",
"requested_at": "2026-10-21T14:05:00Z",
"reviewed_at": "2026-10-21T15:30:00Z",
"limits": [
{
"period": "DAILY",
"currency": "USD",
"amount": "25000.00"
},
{
"period": "ROLLING_30D",
"currency": "USD",
"amount": "100000.00"
}
]
}
]
}Poll until status becomes REVIEWED. The list holds the latest request per corridor, newest first, and returns an empty data array when none has been made.
| Status | Meaning |
|---|---|
REQUESTED | The review is still open. No reviewed_at and no limits yet. |
REVIEWED | The corridor has finished reviewing. limits holds the ceilings in effect afterwards. |
REVIEWED does not mean "approved". The corridor reports the limits in effect after its review. A review can leave the limits exactly as they were.
limits is the snapshot taken at review time and does not change afterwards. For live headroom, go back to step 1 — GET /v1/payments/customers/{customer_id}/limits reports the current ceilings with used and remaining tracking payouts against them.
Updated 3 days ago
