Skip to main content
Sandbox tokens, card numbers, and API keys in this documentation are examples only. Values may differ per environment or tenant. Never use production credentials in shared sandboxes or commit secrets to source control.

Environments and base URLs

EnvironmentBase URL (REST)Notes
CV / integration (default in this doc)https://raas-partner-cv.nomas.cash/v1Example non-production host; your contract may use a different hostname.
mTLS (same logical API)https://mtls-partner-cv.nomas.cash/v1See Introduction for certificate usage.

Authentication in tests

  • Send header api_key on every request (value issued for your tenant in that environment).
  • Scopes in the Partner API are grouped in the OpenAPI tags Partner, Partner Send, and Partner Full. Use an API key that includes the scope required by the endpoint you are calling.
Keep api_key on your server only. Do not embed it in mobile apps or public web clients.

Test card number (sandbox)

Use these sandbox-only PANs where your flow accepts a test card number (for example via VGS or a widget that tokenizes before RaaS). Confirm with Leapfinancial which rows apply to your tenant and processor; lists can change.
NetworkCard numberCVV
Visa4111 1111 1111 1111
Visa4622 9431 2701 3705838
Visa4622 9431 2701 3713043
Visa4622 9431 2701 3721258
Visa4622 9431 2701 3739942
Visa4622 9431 2701 3747370
Mastercard2222 4200 0000 1113
Mastercard2222 6300 0000 1125
Mastercard5555 5555 5555 4444

Card field tokenization (VGS)

Some integrations send sensitive card fields (PAN, CVV) to Very Good Security (VGS) outbound proxy endpoints instead of posting raw values to RaaS. The vault identifier in the hostname is tenant- or environment-specific; replace it with your own value (for example a REST Client variable {{vgsVaultId}} declared in your .http file). Sandbox URL pattern
https://{{vgsVaultId}}.sandbox.verygoodproxy.com/post
Example request (Content-Type: application/json):
POST https://{{vgsVaultId}}.sandbox.verygoodproxy.com/post
Content-Type: application/json

{
    "CardNumber": "4111111111111111",
    "Cvv": "123"
}
Example response (shape may vary slightly by VGS route configuration; tokens below are illustrative):
{
  "data": "{\"CardNumber\": \"41111111\"}",
  "json": {
    "CardNumber": "tok_sandbox_9PNgfqqpdpyQpnD1jYkdw1_1111",
    "Cvv": "tok_sandbox_cE5jCyTLtr2cC666to2ie2"
  }
}
Use the values under json (e.g. tok_sandbox_…) as number / securityCode (or equivalent fields) when calling Partner funding or card endpoints—never send live PAN/CVV to RaaS from untrusted clients.
Do not commit real card data, production vault IDs, or proxy credentials. The PAN/CVV in the request example are test-only patterns for sandbox documentation.

UBN and bank-style test data

For POST /user/funding/source/ubn-account/add/{userToken} (and related flows), sandbox account numbers are often numeric strings in a fixed length for your country (for example a value shaped like 002320275621938815). Validate the exact test account list for your tenant and country with Leap—do not assume one global test account across all partners.

Phones, users, and contacts

  • Use E.164 phone numbers with the correct dial country code for getUserTokenV2 and registration flows.
  • For duplicate contact tests, reuse the same phone under the same userToken and expect a 400-class error with a clear reason / code (see OpenAPI for createContact).

getUserTokenV2 — scenario matrix

Use POST /auth/get-user-token-v2 with a valid api_key so the request reaches this handler. Body: GetUserTokenParams (phoneNumber and/or email, optional countryCode). The table lists handler outcomes (successResponse, badRequestResponse, notFoundResponse, errorResponse) and the 401 case now declared in OpenAPI via @Response<ErrorResponse>(401, "Missing or invalid API key") (enforcement may still occur at the gateway before TSOA). Ready-to-run examples for these rows live in clients/clientv5/partner-ask-v1.http — search for getUserToken-v2 —.
HTTPScenarioHow to reproduceTypical JSON (reason / code)
200Known user by phone or emailE.164 phoneNumber (with +) or email that already exists for the tenant; align countryCode with the number when you send it.{ "userId": "…", "status": "…" } (optional fields depend on tenant / CIP).
401Missing / bad API keyOmit api_key or send an invalid/expired partner key.OpenAPI example: Missing or invalid API key; live stacks may return a gateway-specific body.
400Tenant could not be loadedFirst tenantService.getById returns no tenant for the resolved request.tenant.id (environment-specific).ERROR_INVALID_TENANT
400Missing aliasEmpty JSON {} or omit both phoneNumber and email.ERROR_INVALID_SCHEMA
400Invalid email shapeString that fails the server-side email check, e.g. "no-es-un-email", or an email containing a null byte.ERROR_INVALID_EMAIL_FORMAT
400Phone not E.164phoneNumber without a leading + (e.g. national digits only).INVALID_PHONE_NUMBER
400Country mismatchValid E.164 for one country with countryCode that does not match platform phone validation (e.g. MX mobile with countryCode forced to US).ERROR_COUNTRY_NOT_SUPPORTED
404User not foundemail or phoneNumber that is syntactically valid but not registered in that environment / tenant.ERROR_USER_NOT_FOUND
500Internal / downstream failureNot reliably simulated from a static HTTP file; may appear on datastore, CIP, tenant, TPE, or any unexpected exception after NumiBadRequestError is ruled out.Handler returns the generic internal error (ERROR_INTERNAL_SERVER_ERROR); retry with backoff and support correlation if provided.
For ERROR_COUNTRY_NOT_SUPPORTED, use a real sandbox mobile your TPE accepts, then deliberately pass the wrong countryCode. If validation is stubbed in a local dev stack, this row may not fire until you hit a CV-like environment.
Responses often include both reason (human-readable) and code (machine-readable). Treat 400 as “fix the request or tenant context”; 404 as “user does not exist — register or fix the alias”; 500 as “retry later / escalate with timestamps.” For getUserTokenV2, 500 uses the same generic internal payload (ERROR_INTERNAL_SERVER_ERROR).

registerUserV2 — scenario matrix

POST /auth/register-user-v2. Handler returns 200 with userId when registration is queued; 400 for tenant, country, schema, DOB, already enrolled, or phone validation (NumiBadRequestError); 500 for unexpected or platform errors (generic body, no raw error.message). 401 is documented in OpenAPI (@Response<ErrorResponse>(401, "Missing or invalid API key")).
HTTPScenarioHow to reproduce (minimal)Expected code / body
200New user acceptedValid RegisterUserParams, phone/email not already registered.userId + optional status
401Missing / bad API keyOmit api_key or invalid partner key.OpenAPI 401 description; body may be gateway-shaped.
400Invalid tenant / country / schema / DOB / enrolledMissing tenant, countryCode ≠ tenant, invalid fields, bad DOB, or existing user.ERROR_INVALID_* / ERROR_USER_ALREADY_ENROLLED / phone validation codes
500Platform / unexpectedDownstream failure after validation.ERROR_INTERNAL_SERVER_ERROR

getProfile — scenario matrix

GET /user/profile/{phoneOrEmail}. Resolves a registered user by E.164 phone (with +) or email, loads the subscriber record for createdAt, and enriches the response with CIP process status from cipService.getProcessInfo. Returns a UserProfile with identity, contact, address, optional geo coordinates (latitude, longitude), and CIP status. 404 when the user or subscriber is missing; 500 on unexpected storage/CIP/platform errors (sanitized ErrorResponse, no raw error.message). 401 is declared in OpenAPI (@Response<ErrorResponse>(401, "Missing or invalid API key")). OpenAPI per-status tables come from openapi-examples.json (_mintlifyResponseDescriptions.getProfile); keep this section and that JSON in sync. Ready-to-run examples live in clients/clientv5/partner-ask-v1.http — search for getProfile —.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200Profile OKPath phoneOrEmail is a registered phone or email for the tenant; user has a subscriber record and CIP data.UserProfile (id, names, contact, address, CIP status, createdAt, optional latitude / longitude).
401Missing / bad API keyOmit api_key or send an invalid/expired partner key.OpenAPI 401; body may be gateway-shaped.
404User not foundPhone or email not registered in the tenant.ERROR_USER_NOT_FOUND
404Subscriber not foundUser exists in user store but has no subscriber mapping.ERROR_SUBSCRIBER_NOT_FOUND
422Path validationTSOA path parameter validation failure (rare in normal use).ValidateError
500CIP not foundUser/subscriber exist but CIP record is missing when getProcessInfo runs.ERROR_CIP_NOT_FOUND
500Internal / downstreamUser or subscriber store throws, or other unexpected NumiError after client-error paths ruled out.ERROR_INTERNAL_SERVER_ERROR or mapped NumiError code

listContacts — scenario matrix

GET /user/contacts/{userToken}. Resolves the path userToken via user storage: 404 if there is no user; 200 with an array (possibly empty) when the user exists; 500 if contact storage throws. Use api_key with partner or partner_send scope (401/403 come from the gateway when the key is missing, invalid, or out of scope).
HTTPScenarioHow to reproduce (minimal)Expected code / body
200List OKValid userToken for an existing user.Array of contacts (may be empty)
404Unknown userRandom path segment or deleted user id (not found in user store).ERROR_USER_NOT_FOUND
401No / bad API keyOmit api_key or use a wrong key.Environment-specific
403ScopeKey without partner / partner_send.Environment-specific
500Storage errorRare failure from contact store.ERROR_INTERNAL_SERVER_ERROR

createContact — scenario matrix

POST /user/contacts/{userToken}. 404 when userToken does not resolve to a user; 400 for missing names, bad phone, missing country, duplicates; 500 sanitized on unknown errors (NumiBadRequestError / NumiError mapped in catch). 401 is documented in OpenAPI (same @Response<ErrorResponse>(401, …) pattern as listContacts). 422 TSOA ValidateError is no longer declared on this route; structural validation errors surface as 400 / 500 per handler.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200Contact storedValid body + normalized phone.{ "reason": "Contact created", "code": "OK" }
404Unknown path useruserToken not in user store.ERROR_USER_NOT_FOUND
401Missing / bad API keyOmit api_key or wrong key / scope.OpenAPI 401; body may be gateway-specific.
400Validation / businessMissing firstName/lastName, bad phone, duplicate phone, etc.ERROR_* from ErrorCodes
500UnexpectedRare storage failures after validation.ERROR_INTERNAL_SERVER_ERROR

updateContact — scenario matrix

PUT /user/contacts/{userToken}. 404 when userToken does not resolve to a user; 400 / 500 for payload or storage errors (sanitized). 401 documented in OpenAPI like other contact routes.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200UpdatedValid token + existing contact + valid body.{ "reason": "Contact updated", "code": "OK" }
404Unknown path useruserToken not in user store.ERROR_USER_NOT_FOUND
401Missing / bad API keyOmit api_key or wrong key / scope.OpenAPI 401.
400Invalid payloadBody fails validation rules returned by the handler.ERROR_*
500UnexpectedContact missing or storage error.ERROR_INTERNAL_SERVER_ERROR

getAvailablePaymentMethods — scenario matrix

GET /user/corridors/available-receiver-methodtypes/{userToken} (getAvailableReceiverMethodTypes in code). Returns method type strings for corridors.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200Types resolvedValid user and tenant; corridors configured.["DebitCard", ...]
404Unknown path useruserToken not found in user store.ERROR_USER_NOT_FOUND
401Missing / bad API keyOmit api_key or invalid key for partner / partner_send / partner_full.OpenAPI 401 via @Response<ErrorResponse>.
500Resolution failureTenant/corridor errors or unexpected exception after user resolved.Generic internal reason

getReceivingMethods — scenario matrix

GET /user/funding/source/get-receiving-methods/{userToken}. 400 invalid tenant; 200 SOF list; 500 downstream / NumiError.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200SOF listValid tenant + user + query countries.SourceOfFunding[]
401Missing / bad API keyOmit api_key or invalid partner key.OpenAPI 401 via @Response<ErrorResponse>.
400Invalid tenantRequest without resolvable tenant / missing tenant row.ERROR_INVALID_TENANT
500Service errorFunding service / unexpected errors.ERROR_INTERNAL_SERVER_ERROR or NumiError payload

createFundingCard (add card) — scenario matrix

POST /user/funding/source/card/add/{userToken} (OperationId: createFundingCard). 400 card/issuer validation; 200 existing or new PM; 500 unexpected.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200Card added or duplicate returnedValid sandbox token + valid card payload (or duplicate number).RaaSPaymentMethod
401Missing / bad API keyOmit api_key or key without partner_send / partner.OpenAPI 401 via @Response<ErrorResponse>.
400Declined / invalidBad expiry, BIN, processor decline, user not found.Parsed card error object
500UnexpectedNon-NumiBadRequestError failures.ERROR_INTERNAL_SERVER_ERROR

addUBNAccount — scenario matrix

POST /user/funding/source/ubn-account/add/{userToken}. 403 user/tenant; 400 UBN validation / duplicate; 500 platform failure.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200UBN addedValid user, subscriber, sandbox UBN.AddPaymentMethodResponse
401Missing / bad API keyOmit api_key or invalid multi-scope key.OpenAPI 401 via @Response<ErrorResponse>.
400Invalid UBN / duplicateBad account algorithm or PAYMENTMETHOD_ALREADY_EXISTS.UBN_VALIDATION_ERROR / UBN_ALREADY_ADDED
403User/tenantUnknown userToken or tenant mismatch paths.USER_NOT_FOUND / INVALID_TENANT (as returned by handler)
500PlatformNumiError / unknown errors.ERROR_INTERNAL_SERVER_ERROR or mapped NumiError

getPaymentMethodV2 — scenario matrix

GET /user/funding/source/get-payment-method-v2/{userToken}?id=.... 200 when the payment method exists for the subscriber; 404 when there is no subscriber or the id is not in the user’s methods; 400 for other NumiBadRequestError paths from downstream; 500 for NumiError or unexpected failures.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200PM foundValid userToken, subscriber, existing id.RaaSPartnerPaymentMethod
401Missing / bad API keyOmit api_key or invalid key.OpenAPI 401 via @Response<ErrorResponse>.
400Bad requestOther NumiBadRequestError from funding/connectors (not PM-not-found).reason + code
404Unknown path useruserToken not in user store.ERROR_USER_NOT_FOUND
404Subscriber missingUser path resolves but has no subscriber row.ERROR_SUBSCRIBER_NOT_FOUND
404PM not in walletValid user + random/non-owned id (e.g. new UUID).ERROR_PAYMENT_METHOD_NOT_FOUND
500InternalNumiError or unexpected exception.ERROR_INTERNAL_SERVER_ERROR or mapped NumiError

requestMoneyV2 — scenario matrix

POST /user/operations/request-money-v2/{userToken}. 404 when path userToken does not resolve; 400 for corridor / contact / PM validation; 500 uses mapped NumiError or generic internal (no raw exception text). 401 in OpenAPI for missing/invalid API key.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200Request createdValid payload + corridor + destination PM.OperationResponsePartner
401Missing / bad API keyOmit api_key or key without partner / partner_full.OpenAPI 401.
404Unknown path useruserToken not in user store.ERROR_USER_NOT_FOUND
400ValidationUnsupported destination, PM, or corridor rules.ERROR_* / handler reason+code
500UnexpectedNumiError or unknown after bad-request handling.ERROR_INTERNAL_SERVER_ERROR or errorCode

operationQuoteV2 — scenario matrix

POST /user/operations/operation-quote-v2/{userToken}. 400 invalid quotation fields; 500 tenant/user/rate failures; 401 documented in OpenAPI.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200Quote OKValid recipient id, amounts, PM ids.RaasQuoteTransactionResponse
401Missing / bad API keyOmit api_key or invalid partner_send / partner_full key.OpenAPI 401.
400Invalid payloadEmpty recipient, zero amount, empty currency.ERROR_INVALID_QUOTATION_REQUEST_DATA
500InternalDownstream / unexpected.INTERNAL_SERVER_ERROR or mapped codes

getOperationStatus — scenario matrix

GET /user/operations/status/{userToken}/{operationId}. 404 unknown user; 400 NumiBadRequestError; 500 otherwise; 401 in OpenAPI.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200StatusResolved user + valid operation id.Status string
401Missing / bad API keyOmit api_key or invalid partner / partner_send.OpenAPI 401.
404Unknown path useruserToken not resolved.ERROR_USER_NOT_FOUND
400Bad requestOperation service NumiBadRequestError.ErrorResponse
500InternalUnexpected / NumiError.Generic or errorCode

getOperationQuote — scenario matrix

POST /user/operations/quotation/{userToken}. Same auth pattern as other operations routes; 401 in OpenAPI.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200QuoteValid user + QuoteTransactionBase.RaasQuoteTransactionResponse
401Missing / bad API keyOmit api_key.OpenAPI 401.
404Unknown path useruserToken not in user store.ERROR_USER_NOT_FOUND
400Bad inputQuote validation failures.Mapped ErrorCodes
500InternalMissing tenant, invalid quotation data path, etc.ERROR_INTERNAL_SERVER_ERROR or specific code

preQuote — scenario matrix

POST /user/operations/pre-quote/{userToken}. 500 on market/integration errors; 401 in OpenAPI.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200Pre-quoteValid tenant + PartnerPreQuoteRequest.RaasPreQuoteResponse
401Missing / bad API keyOmit api_key or invalid key.OpenAPI 401.
500InternalNumiError or unexpected.ERROR_INTERNAL_SERVER_ERROR or mapped

getOperation (operation detail) — scenario matrix

GET /user/operations/detail/{id}. 500 when operation missing or tenant mismatch (OPERATION_NOT_FOUND); 401 in OpenAPI.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200DetailOperation exists for partner tenant.OperationDetailResponse
401Missing / bad API keyOmit api_key or invalid multi-scope key.OpenAPI 401.
500Not found / errorWrong id or tenant mismatch.ERROR_OPERATION_NOT_FOUND or internal

getOperations — scenario matrix

GET /user/operations/{userToken}. 400 when user tenant ≠ request tenant; 401 in OpenAPI.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200HistoryValid user for tenant.OperationDetail[]
401Missing / bad API keyOmit api_key.OpenAPI 401.
400Tenant mismatchuserToken belongs to another tenant.ErrorResponse
500InternalDatastore errors.ERROR_INTERNAL_SERVER_ERROR

getFrequentContacts — scenario matrix

GET /user/operations/frequent/{userToken}/{limit}. Returns the top limit contacts derived from recent operations for userToken. OpenAPI merges per-status scenario tables from openapi-examples.json (_mintlifyResponseDescriptionsgetFrequentContacts); keep this section and that JSON in sync.
HTTPScenarioHow to reproduce (minimal)Expected code / body
200Frequent listValid userToken + positive numeric limit within supported bounds.ContactInfo[] (may be empty).
401Missing / bad API keyOmit api_key or use a key without partner / partner_send / partner_full as required by @Security.OpenAPI 401 (@Response<ErrorResponse>(401, "Missing or invalid API key")).
400Bad input / NumiBadRequestErrorInvalid limit (non-numeric, ≤ 0), or service rejects the request with NumiBadRequestError.ErrorResponse with mapped reason / code.
500Indexed query / internalDownstream failure from getLastOperationsContact or unexpected exception after validation.ERROR_INTERNAL_SERVER_ERROR (sanitized body; no raw stack or error.message).

Webhooks and async events

  • Register a reachable HTTPS URL (or tunnel such as ngrok) for webhook callbacks in non-production.
  • Verify signature / shared secret handling if your integration consumes outbound events.
  • Use a unique correlationId on money operations so support can correlate logs across systems.

Correlation IDs for money operations

  • requestMoney requests must include a correlationId. That same value is carried into the related funding operation, so request money and its funding step share one correlation boundary for tracing and support.
  • A standalone or spontaneous send money (not tied to that request-money → funding chain) must use its own correlationId.
  • Treat correlationId as unique per distinct money operation. The only exception is the linked case above: funding reuses the correlationId you sent with requestMoney.