Download OpenAPI specification:Download
Throughout this document and the Velo platform the following terms are used:
This document describes the Velo APIs a partner uses to run a complete customer lifecycle over the API, with no Velo-hosted UI required:
POST /v2/payors with your own reference (payorXid), their address and identity. The create is idempotent on your reference: replaying it returns the customer you already created.This is a working integration document prepared for partner hand-off and is not the general Velo Payments API reference.
The Velo Payments API is REST based and uses the JSON format for requests and responses.
Most calls are secured using OAuth 2 security and require a valid authentication access token for successful operation. See the Authentication section for details.
Where a dynamic value is required in the examples below, the {token} format is used, suggesting that the caller needs to supply the appropriate value of the token in question (without including the { or } characters).
Where curl examples are given, the –d @filename.json approach is used, indicating that the request body should be placed into a file named filename.json in the current directory. Each of the curl examples in this document should be considered a single line on the command-line, regardless of how they appear in print.
Once Velo backoffice staff have added your organization as a payor within the Velo platform sandbox, they will create you a payor Id, an API key and an API secret and share these with you in a secure manner.
You will need to use these values to authenticate with the Velo platform in order to gain access to the APIs. The steps to take are explained in the following:
create a string comprising the API key (e.g. 44a9537d-d55d-4b47-8082-14061c2bcdd8) and API secret (e.g. c396b26b-137a-44fd-87f5-34631f8fd529) with a colon between them. E.g. 44a9537d-d55d-4b47-8082-14061c2bcdd8:c396b26b-137a-44fd-87f5-34631f8fd529
base64 encode this string. E.g.: NDRhOTUzN2QtZDU1ZC00YjQ3LTgwODItMTQwNjFjMmJjZGQ4OmMzOTZiMjZiLTEzN2EtNDRmZC04N2Y1LTM0NjMxZjhmZDUyOQ==
create an HTTP Authorization header with the value set to e.g. Basic NDRhOTUzN2QtZDU1ZC00YjQ3LTgwODItMTQwNjFjMmJjZGQ4OmMzOTZiMjZiLTEzN2EtNDRmZC04N2Y1LTM0NjMxZjhmZDUyOQ==
perform the Velo authentication REST call using the HTTP header created above e.g. via curl:
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Basic NDRhOTUzN2QtZDU1ZC00YjQ3LTgwODItMTQwNjFjMmJjZGQ4OmMzOTZiMjZiLTEzN2EtNDRmZC04N2Y1LTM0NjMxZjhmZDUyOQ==" \
'https://api.sandbox.velopayments.com/v1/authenticate?grant_type=client_credentials'
If successful, this call will result in a 200 HTTP status code and a response body such as:
{
"access_token":"19f6bafd-93fd-4747-b229-00507bbc991f",
"token_type":"bearer",
"expires_in":1799,
"scope":"..."
}
Following successful authentication, the value of the access_token field in the response (indicated in green above) should then be presented with all subsequent API calls to allow the Velo platform to validate that the caller is authenticated.
This is achieved by setting the HTTP Authorization header with the value set to e.g. Bearer 19f6bafd-93fd-4747-b229-00507bbc991f such as the curl example below:
-H "Authorization: Bearer 19f6bafd-93fd-4747-b229-00507bbc991f "
If you make other Velo API calls which require authorization but the Authorization header is missing or invalid then you will get a 401 HTTP status response.
Following is a list of Http Status codes that could be returned by the platform
| Status Code | Description |
| -----------------------| -------------------------------------------------------------------------------------|
| 200 OK | The request was successfully processed and usually returns a json response |
| 201 Created | A resource was created and a Location header is returned linking to the new resource |
| 202 Accepted | The request has been accepted for processing |
| 204 No Content | The request has been processed and there is no response (usually deletes and updates)|
| 400 Bad Request | The request is invalid and should be fixed before retrying |
| 401 Unauthorized | Authentication has failed, usually means the token has expired |
| 403 Forbidden | The user does not have permissions for the request |
| 404 Not Found | The resource was not found |
| 409 Conflict | The resource already exists and there is a conflict |
| 429 Too Many Requests | The user has submitted too many requests in a given amount of time |
| 5xx Server Error | Platform internal error (should rarely happen) |
A Payor is the entity which is sending money. Here you will find the available APIs for working with Payors.
Create a Payor
Details of Payor to create
| type | string (PayorTypeEnum) Enum: "Individual" "Company" Whether the payor is a person or a business. Same vocabulary as PayeeTypeEnum - the platform already asks this about payees, and answering it differently for payors would be a distinction without a difference. Payors created before this field existed are companies. (PayeeTypeEnum carries a note that it is duplicated in invite-service and must stay in sync; the shared home for all three is oa3-common.) |
object (IndividualDetailsV2) The person a payor IS, when the payor is an individual. Deliberately the same fields a company's associated people carry, so one shape describes a human wherever they appear. Address is not here - it is the payor's own address, which an individual shares. | |
| payorName | string [ 2 .. 100 ] characters The name of the payor. Required for a company; for an individual it is composed from their name and must not be supplied. Company names must be unique - two businesses cannot share one - which is not true of people, so no such check applies to them. |
| payorXid | string [ 3 .. 128 ] characters A unique identifier that an external system uses to reference the payor in their system |
required | object (PayorAddressV2) |
| primaryContactName | string [ 2 .. 100 ] characters Name of primary contact for the payor. Required for a company, which is not a person you can phone and so must nominate one. An individual IS the contact, so this is taken from |
| primaryContactPhone | string [ 7 .. 30 ] characters ^\+?[1-9]\d{1,14}$ Primary contact phone number for the payor. |
| primaryContactEmail | string <email> [ 6 .. 255 ] characters Primary contact email for the payor. |
| kycState | string (KycStateEnum) Enum: "FAILED_KYC" "PASSED_KYC" "REQUIRES_KYC" The kyc state of the payor. |
| collectiveAlias | string [ 1 .. 100 ] characters How the payor has chosen to refer to payees. |
| supportContact | string [ 6 .. 128 ] characters The payor’s support contact email address. |
| dbaName | string [ 1 .. 100 ] characters The payor’s 'Doing Business As' name. |
| managingPayees | boolean Indicates whether or not the payor is solely responsible for managing its payees. |
{- "primaryContactName": "Joe Buck",
- "supportContact": "support@example.com",
- "payorXid": "ABC_201234",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "individual": {
- "nameLast": "Lovelace",
- "nameFirst": "Ada",
- "occupation": "Software Engineer",
- "phone": 14155550100,
- "dateOfBirth": "1990-04-12T00:00:00.000+0000",
- "nationalIdentification": "123-45-6789",
- "residencyCountry": "US",
- "govIdCountry": "US",
- "nameMiddle": "nameMiddle",
- "email": "email",
- "pepStatus": false,
- "citizenshipCountry": "US"
}, - "managingPayees": true,
- "dbaName": "Some Biz",
- "type": "Individual",
- "primaryContactPhone": "123-123-1234",
- "collectiveAlias": "Payee",
- "kycState": "PASSED_KYC",
- "primaryContactEmail": "joe.buck@example.com",
- "payorName": "Example, Corp"
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Get a Single Payor by Id.
| payorId required | string <uuid> The account owner Payor ID |
$ curl 'https://api.sandbox.velopayments.com/v2/payors/126969bd-6a18-47ec-96e1-57559afecf32' -i -X GET \ -H 'Authorization: Bearer 3387c417-464c-41a6-b25e-6630f0a06093' \ -H 'Content-Type: application/json'
{- "primaryContactName": "Joe Buck",
- "payeeGracePeriodProcessingEnabled": true,
- "supportContact": "support@example.com",
- "payorXid": "ABC_201234",
- "nameFirst": "nameFirst",
- "occupation": "occupation",
- "includesReports": true,
- "managingPayees": true,
- "payorType": "Individual",
- "allowsLanguageChoice": true,
- "language": "EN",
- "govIdCountry": "US",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "US",
- "createdAt": "2021-12-08T14:41:02.354982Z",
- "provider": "provider",
- "maxMasterPayorAdmins": 5,
- "manualLockout": true,
- "paymentRails": "paymentRails",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "residencyCountry": "US",
- "primaryContactEmail": "joe.buck@example.com",
- "usdTxnValueReportingThreshold": 1000000,
- "pepStatus": true,
- "payorName": "Example Corp",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "openBankingEnabled": true,
- "dateOfBirth": "1990",
- "dbaName": "Some Biz",
- "primaryContactPhone": "123-123-1234",
- "payeeGracePeriodDays": 0,
- "nameLast": "nameLast",
- "reminderEmailsOptOut": true,
- "collectiveAlias": "Vendors",
- "nationalIdentification": "***-**-6789",
- "kycState": "PASSED_KYC",
- "wuCustomerId": "wuCustomerId",
- "remoteSystemIds": [
- "REMOTE_SYSTEM_ID",
- "REMOTE_SYSTEM_ID"
]
}Create an application for the given Payor ID.
Applications provide a means to group your API Keys
For example you might have an SAP application that you wish to integrate with Velo
You can create an application and then create one or more API keys for the application
| payorId required | string <uuid> The account owner Payor ID |
Details of application to create
| name required | string [ 2 .. 100 ] characters The name of the application. |
| description | string or null [ 2 .. 1024 ] characters Description of the application. |
{- "name": "SAP",
- "description": "SAP Application integration"
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Create an an API key for the given payor Id and application Id
You can create multiple API Keys for a given application
API Keys are programmatic users for integrating your application with the Velo platform
The response will return the API Key and the secret. This is the only time you will be able to see the secret
| payorId required | string <uuid> The account owner Payor ID |
| applicationId required | string <uuid> Application ID |
Details of application API key to create
| name required | string [ 2 .. 100 ] characters A name for the key. |
| description | string or null [ 2 .. 1024 ] characters Description of the key. |
| roles required | Array of strings = 1 items Items Enum: "payor.admin" "payor.support" A role to assign to the key. If you want your API key to have write access then assign the role velo.payor.admin A later version will change this property from a list to string |
{- "roles": [
- "payor.admin"
], - "name": "SAP Key 01",
- "description": "An API Key for the SAP Application"
}{- "apiKey": "385d4506-e7dd-446e-a092-5f30b98e7b26",
- "apiSecret": "f25767d9-342a-48ac-a788-0a7a38ae6fb3"
}Add Payor Logo
Logo file is used in your branding and in the emails Velo sends to your customers
| payorId required | string <uuid> The account owner Payor ID |
Image file to upload
| logo | string <binary> |
$ curl 'https://api.sandbox.velopayments.com/v1/payors/450ecb66-df18-4d0c-b557-f718782775df/branding/logos' -i -X POST \ -H 'Content-Type: multipart/form-data' \ -F 'logo=@mylogo.png;type=image/png'
{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Get the payor branding details.
| payorId required | string <uuid> The account owner Payor ID |
$ curl 'https://api.sandbox.velopayments.com/v1/payors/450ecb66-df18-4d0c-b557-f718782775df/branding' -i -X GET \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer d60eef1c-bea6-4f7e-8755-e916268ad4ff'
{- "supportContact": "support@example.com",
- "collectiveAlias": "Contractors",
- "dbaName": "Key West Imports",
- "payorName": "Key West Imports, Inc"
}Get the payor's KYC/KYB profile with associated persons and agreement acceptances. Sensitive values (taxId, birthdate, nationalIdentification) are masked. A SYSTEM principal may pass sensitive=true to receive the decrypted projection — this is the rails-service pull for provider KYB submission. Returns 404 when the payor has no profile (non-crypto payors — the portal bootstrap check renders nothing in that case).
| payorId required | string <uuid> The account owner Payor ID |
| sensitive | boolean Default: false SYSTEM principals only — return decrypted sensitive fields |
{- "providerVerificationStatus": "NONE",
- "watchlistStatus": "NONE",
- "businessDescription": "businessDescription",
- "profileStatus": "DRAFT",
- "reviewedAt": "2000-01-23T04:56:07.000+00:00",
- "sourceOfFunds": "BUSINESS_REVENUE",
- "targetRailsId": "BITGO",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "legalEntityType": "LLC",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "expectedMonthlyVolume": "FROM_100K_TO_1M",
- "submittedAt": "2000-01-23T04:56:07.000+00:00",
- "updatedAt": "2000-01-23T04:56:07.000+00:00",
- "providerFeedbackAt": "2000-01-23T04:56:07.000+00:00",
- "watchlistStatusUpdatedAt": "2000-01-23T04:56:07.000+00:00",
- "website": "website",
- "reviewComment": "reviewComment",
- "verificationStatus": "ACTION_REQUIRED",
- "accountType": "ENTITY",
- "agreements": [
- {
- "signerNameSnapshot": "John Smith",
- "acceptedFromIp": "203.0.113.10",
- "agreementKey": "csa",
- "railsId": "BITGO",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "contractVersion": "2026-06",
- "signerPersonId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "acceptedAt": "2000-01-23T04:56:07.000+00:00"
}, - {
- "signerNameSnapshot": "John Smith",
- "acceptedFromIp": "203.0.113.10",
- "agreementKey": "csa",
- "railsId": "BITGO",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "contractVersion": "2026-06",
- "signerPersonId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "acceptedAt": "2000-01-23T04:56:07.000+00:00"
}
], - "formationDate": "2000-01-23",
- "persons": [
- {
- "watchlistStatusUpdatedAt": "2000-01-23T04:56:07.000+00:00",
- "role": "CONTROL_PERSON",
- "nameFirst": "John",
- "birthdate": "1980",
- "occupation": "occupation",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "watchlistStatus": "NONE",
- "govIdCountry": "USA",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "USA",
- "nameLast": "Smith",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "phone": "phone",
- "nationalIdentification": "***-**-6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "residencyCountry": "USA",
- "pepStatus": true,
- "email": "email",
- "ownershipPercentage": 25.5,
- "updatedAt": "2000-01-23T04:56:07.000+00:00"
}, - {
- "watchlistStatusUpdatedAt": "2000-01-23T04:56:07.000+00:00",
- "role": "CONTROL_PERSON",
- "nameFirst": "John",
- "birthdate": "1980",
- "occupation": "occupation",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "watchlistStatus": "NONE",
- "govIdCountry": "USA",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "USA",
- "nameLast": "Smith",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "phone": "phone",
- "nationalIdentification": "***-**-6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "residencyCountry": "USA",
- "pepStatus": true,
- "email": "email",
- "ownershipPercentage": 25.5,
- "updatedAt": "2000-01-23T04:56:07.000+00:00"
}
], - "registeredName": "Acme Holdings LLC",
- "mailingAddress": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "taxId": "**-***6789",
- "primaryOperationsCountry": "USA",
- "actionsRequired": [
- {
- "reason": "DOCUMENT_REQUIRED",
- "path": "individual.address",
- "docType": "PROOF_OF_ADDRESS",
- "message": "The address document is older than 90 days - upload a recent one"
}, - {
- "reason": "DOCUMENT_REQUIRED",
- "path": "individual.address",
- "docType": "PROOF_OF_ADDRESS",
- "message": "The address document is older than 90 days - upload a recent one"
}
], - "billingAddress": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "providerFeedback": "providerFeedback",
- "incorporationCountry": "USA"
}Create (backoffice only — fixes accountType and targetRailsId) or update a payor's KYC/KYB profile. Payors may update while the profile is DRAFT, REJECTED or ACTION_REQUIRED; backoffice may also update while SUBMITTED. Returns 409 for edits in any other state — APPROVED profiles change through the amendment flow.
| payorId required | string <uuid> The account owner Payor ID |
KYC profile fields
| accountType required | string (KycAccountType) Enum: "INDIVIDUAL" "ENTITY" KYC account flavor. INDIVIDUAL profiles carry exactly one PRINCIPAL person; ENTITY profiles carry the full associated-persons structure. |
| targetRailsId | string or null <= 32 characters Rail this onboarding targets (e.g. BITGO). Null = Velo-only KYC — no provider leg, no rail enablement on approval. |
| registeredName | string [ 2 .. 255 ] characters Exact legal name for KYB — may differ from payorName |
| legalEntityType | string <= 32 characters Validated against the configured list (e.g. LLC, C_CORP, S_CORP...) |
| taxId | string^\d{2}-?\d{7}$ EIN. Stored encrypted; returned masked. |
| formationDate | string <date> Must be in the past |
| incorporationCountry | string (ISO 3166 2 Character Country Code) = 2 characters ^[A-Z]{2}$ Valid ISO 3166 2 character country code. See the ISO specification for details. |
| primaryOperationsCountry | string (ISO 3166 2 Character Country Code) = 2 characters ^[A-Z]{2}$ Valid ISO 3166 2 character country code. See the ISO specification for details. |
| website | string <= 255 characters |
| businessDescription | string [ 20 .. 1000 ] characters |
| expectedMonthlyVolume | string <= 24 characters Validated against the configured band list (e.g. UNDER_10K..OVER_10M) |
| sourceOfFunds | string <= 48 characters Validated against the configured list |
object (PayorAddressV2) | |
object (PayorAddressV2) |
{- "businessDescription": "Wholesale distribution of industrial fasteners across North America",
- "accountType": "ENTITY",
- "formationDate": "2015-06-01T00:00:00.000+0000",
- "sourceOfFunds": "BUSINESS_REVENUE",
- "targetRailsId": "BITGO",
- "registeredName": "Acme Holdings LLC",
- "mailingAddress": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "taxId": "12-3456789",
- "primaryOperationsCountry": "US",
- "legalEntityType": "LLC",
- "expectedMonthlyVolume": "FROM_100K_TO_1M",
- "billingAddress": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "incorporationCountry": "US"
}{- "providerVerificationStatus": "NONE",
- "watchlistStatus": "NONE",
- "businessDescription": "businessDescription",
- "profileStatus": "DRAFT",
- "reviewedAt": "2000-01-23T04:56:07.000+00:00",
- "sourceOfFunds": "BUSINESS_REVENUE",
- "targetRailsId": "BITGO",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "legalEntityType": "LLC",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "expectedMonthlyVolume": "FROM_100K_TO_1M",
- "submittedAt": "2000-01-23T04:56:07.000+00:00",
- "updatedAt": "2000-01-23T04:56:07.000+00:00",
- "providerFeedbackAt": "2000-01-23T04:56:07.000+00:00",
- "watchlistStatusUpdatedAt": "2000-01-23T04:56:07.000+00:00",
- "website": "website",
- "reviewComment": "reviewComment",
- "verificationStatus": "ACTION_REQUIRED",
- "accountType": "ENTITY",
- "agreements": [
- {
- "signerNameSnapshot": "John Smith",
- "acceptedFromIp": "203.0.113.10",
- "agreementKey": "csa",
- "railsId": "BITGO",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "contractVersion": "2026-06",
- "signerPersonId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "acceptedAt": "2000-01-23T04:56:07.000+00:00"
}, - {
- "signerNameSnapshot": "John Smith",
- "acceptedFromIp": "203.0.113.10",
- "agreementKey": "csa",
- "railsId": "BITGO",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "contractVersion": "2026-06",
- "signerPersonId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "acceptedAt": "2000-01-23T04:56:07.000+00:00"
}
], - "formationDate": "2000-01-23",
- "persons": [
- {
- "watchlistStatusUpdatedAt": "2000-01-23T04:56:07.000+00:00",
- "role": "CONTROL_PERSON",
- "nameFirst": "John",
- "birthdate": "1980",
- "occupation": "occupation",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "watchlistStatus": "NONE",
- "govIdCountry": "USA",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "USA",
- "nameLast": "Smith",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "phone": "phone",
- "nationalIdentification": "***-**-6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "residencyCountry": "USA",
- "pepStatus": true,
- "email": "email",
- "ownershipPercentage": 25.5,
- "updatedAt": "2000-01-23T04:56:07.000+00:00"
}, - {
- "watchlistStatusUpdatedAt": "2000-01-23T04:56:07.000+00:00",
- "role": "CONTROL_PERSON",
- "nameFirst": "John",
- "birthdate": "1980",
- "occupation": "occupation",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "watchlistStatus": "NONE",
- "govIdCountry": "USA",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "USA",
- "nameLast": "Smith",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "phone": "phone",
- "nationalIdentification": "***-**-6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "residencyCountry": "USA",
- "pepStatus": true,
- "email": "email",
- "ownershipPercentage": 25.5,
- "updatedAt": "2000-01-23T04:56:07.000+00:00"
}
], - "registeredName": "Acme Holdings LLC",
- "mailingAddress": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "taxId": "**-***6789",
- "primaryOperationsCountry": "USA",
- "actionsRequired": [
- {
- "reason": "DOCUMENT_REQUIRED",
- "path": "individual.address",
- "docType": "PROOF_OF_ADDRESS",
- "message": "The address document is older than 90 days - upload a recent one"
}, - {
- "reason": "DOCUMENT_REQUIRED",
- "path": "individual.address",
- "docType": "PROOF_OF_ADDRESS",
- "message": "The address document is older than 90 days - upload a recent one"
}
], - "billingAddress": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "providerFeedback": "providerFeedback",
- "incorporationCountry": "USA"
}Add an associated person to the payor's KYC profile. Allowed while the profile is DRAFT, REJECTED or ACTION_REQUIRED.
| payorId required | string <uuid> The account owner Payor ID |
Person details
| role required | string (KycPersonRole) Enum: "BENEFICIAL_OWNER" "CONTROL_PERSON" "AUTHORIZED_SIGNER" "PRINCIPAL" Role of an associated person. ENTITY profiles require exactly one CONTROL_PERSON and every owner of 10% or more as BENEFICIAL_OWNER; INDIVIDUAL profiles have exactly one PRINCIPAL. One role per record — the same human may appear in multiple records. |
| ownershipPercentage | number [ 0 .. 100 ] Required when role is BENEFICIAL_OWNER |
| nameFirst required | string [ 1 .. 100 ] characters |
| nameMiddle | string <= 100 characters |
| nameLast required | string [ 1 .. 100 ] characters |
| birthdate | string <date> Must be at least 18 years ago. Stored encrypted; returned year-only. |
| nationalIdentification | string^\d{3}-?\d{2}-?\d{4}$ SSN or ITIN. Stored encrypted; returned masked. |
| occupation | string <= 128 characters Validated against the configured list |
| pepStatus | boolean Default: false Politically exposed person |
| citizenshipCountry | string (ISO 3166 2 Character Country Code) = 2 characters ^[A-Z]{2}$ Valid ISO 3166 2 character country code. See the ISO specification for details. |
| residencyCountry | string (ISO 3166 2 Character Country Code) = 2 characters ^[A-Z]{2}$ Valid ISO 3166 2 character country code. See the ISO specification for details. |
| govIdCountry | string (ISO 3166 2 Character Country Code) = 2 characters ^[A-Z]{2}$ Valid ISO 3166 2 character country code. See the ISO specification for details. |
string <email> [ 6 .. 255 ] characters Required for CONTROL_PERSON and PRINCIPAL roles | |
| phone | string^\+?[1-9]\d{1,14}$ E.164 |
object (PayorAddressV2) |
{- "role": "CONTROL_PERSON",
- "nameFirst": "John",
- "birthdate": "1980-01-15T00:00:00.000+0000",
- "occupation": "Chief Executive Officer",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "govIdCountry": "US",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "US",
- "nameLast": "Smith",
- "phone": 14155550100,
- "nationalIdentification": "123-45-6789",
- "residencyCountry": "US",
- "pepStatus": false,
- "email": "email",
- "ownershipPercentage": 25.5
}{- "watchlistStatusUpdatedAt": "2000-01-23T04:56:07.000+00:00",
- "role": "CONTROL_PERSON",
- "nameFirst": "John",
- "birthdate": "1980",
- "occupation": "occupation",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "watchlistStatus": "NONE",
- "govIdCountry": "USA",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "USA",
- "nameLast": "Smith",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "phone": "phone",
- "nationalIdentification": "***-**-6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "residencyCountry": "USA",
- "pepStatus": true,
- "email": "email",
- "ownershipPercentage": 25.5,
- "updatedAt": "2000-01-23T04:56:07.000+00:00"
}Remove an associated person. Allowed while the profile is DRAFT, REJECTED or ACTION_REQUIRED.
| payorId required | string <uuid> The account owner Payor ID |
| personId required | string <uuid> The KYC associated-person ID |
{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 403
}Update an associated person. Allowed while the profile is DRAFT, REJECTED or ACTION_REQUIRED. Identity-field changes re-derive the screening subject and re-trigger screening on the next submission.
| payorId required | string <uuid> The account owner Payor ID |
| personId required | string <uuid> The KYC associated-person ID |
Person details
| role required | string (KycPersonRole) Enum: "BENEFICIAL_OWNER" "CONTROL_PERSON" "AUTHORIZED_SIGNER" "PRINCIPAL" Role of an associated person. ENTITY profiles require exactly one CONTROL_PERSON and every owner of 10% or more as BENEFICIAL_OWNER; INDIVIDUAL profiles have exactly one PRINCIPAL. One role per record — the same human may appear in multiple records. |
| ownershipPercentage | number [ 0 .. 100 ] Required when role is BENEFICIAL_OWNER |
| nameFirst required | string [ 1 .. 100 ] characters |
| nameMiddle | string <= 100 characters |
| nameLast required | string [ 1 .. 100 ] characters |
| birthdate | string <date> Must be at least 18 years ago. Stored encrypted; returned year-only. |
| nationalIdentification | string^\d{3}-?\d{2}-?\d{4}$ SSN or ITIN. Stored encrypted; returned masked. |
| occupation | string <= 128 characters Validated against the configured list |
| pepStatus | boolean Default: false Politically exposed person |
| citizenshipCountry | string (ISO 3166 2 Character Country Code) = 2 characters ^[A-Z]{2}$ Valid ISO 3166 2 character country code. See the ISO specification for details. |
| residencyCountry | string (ISO 3166 2 Character Country Code) = 2 characters ^[A-Z]{2}$ Valid ISO 3166 2 character country code. See the ISO specification for details. |
| govIdCountry | string (ISO 3166 2 Character Country Code) = 2 characters ^[A-Z]{2}$ Valid ISO 3166 2 character country code. See the ISO specification for details. |
string <email> [ 6 .. 255 ] characters Required for CONTROL_PERSON and PRINCIPAL roles | |
| phone | string^\+?[1-9]\d{1,14}$ E.164 |
object (PayorAddressV2) |
{- "role": "CONTROL_PERSON",
- "nameFirst": "John",
- "birthdate": "1980-01-15T00:00:00.000+0000",
- "occupation": "Chief Executive Officer",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "govIdCountry": "US",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "US",
- "nameLast": "Smith",
- "phone": 14155550100,
- "nationalIdentification": "123-45-6789",
- "residencyCountry": "US",
- "pepStatus": false,
- "email": "email",
- "ownershipPercentage": 25.5
}{- "watchlistStatusUpdatedAt": "2000-01-23T04:56:07.000+00:00",
- "role": "CONTROL_PERSON",
- "nameFirst": "John",
- "birthdate": "1980",
- "occupation": "occupation",
- "address": {
- "country": "US",
- "countyOrProvince": "FL",
- "line4": "line4",
- "city": "Key West",
- "line3": "line3",
- "line2": "line2",
- "line1": "500 Duval St",
- "zipOrPostcode": "33945"
}, - "watchlistStatus": "NONE",
- "govIdCountry": "USA",
- "nameMiddle": "nameMiddle",
- "citizenshipCountry": "USA",
- "nameLast": "Smith",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "phone": "phone",
- "nationalIdentification": "***-**-6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "residencyCountry": "USA",
- "pepStatus": true,
- "email": "email",
- "ownershipPercentage": 25.5,
- "updatedAt": "2000-01-23T04:56:07.000+00:00"
}Record acceptance of a rail-provider agreement (e.g. BitGo csa/mpa). The signer must be a CONTROL_PERSON or AUTHORIZED_SIGNER on ENTITY profiles, or the PRINCIPAL on INDIVIDUAL profiles. Unique per (profile, railsId, agreementKey).
| payorId required | string <uuid> The account owner Payor ID |
Agreement acceptance evidence
| railsId required | string <= 32 characters |
| agreementKey required | string <= 32 characters Opaque provider agreement key from the per-rail descriptor (e.g. csa, mpa) |
| contractVersion | string <= 16 characters |
| signerNameFull | string [ 2 .. 255 ] characters The name the signer accepted under, as captured at acceptance. Recorded verbatim - correcting the person record later must not rewrite the evidence. Falls back to the signer's name on file when omitted. |
| signerPersonId | string <uuid> The associated person accepting on behalf of a company - required for company profiles, must be omitted for individuals (the payor is the signer). |
| acceptedAt required | string <date-time> |
| acceptedFromIp | string <= 45 characters IPv4 or IPv6 |
{- "acceptedFromIp": "203.0.113.10",
- "agreementKey": "csa",
- "railsId": "BITGO",
- "signerNameFull": "Ada M Lovelace",
- "contractVersion": "2026-06",
- "signerPersonId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "acceptedAt": "2000-01-23T04:56:07.000+00:00"
}{- "signerNameSnapshot": "John Smith",
- "acceptedFromIp": "203.0.113.10",
- "agreementKey": "csa",
- "railsId": "BITGO",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "contractVersion": "2026-06",
- "signerPersonId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "acceptedAt": "2000-01-23T04:56:07.000+00:00"
}Submission readiness — required fields, documents and agreements still missing, plus current screening states. Drives the portal wizard's "what's missing" panel. Requirements resolve from the profile's accountType and targetRailsId descriptor.
| payorId required | string <uuid> The account owner Payor ID |
{- "missingFields": [
- "registeredName",
- "taxId",
- "persons.controlPerson"
], - "pendingAgreements": [
- "csa",
- "mpa"
], - "ready": true,
- "pendingDocuments": [
- "W9",
- "PROOF_OF_SIGNATORIES"
], - "watchlist": {
- "persons": [
- {
- "personId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "status": "NONE"
}, - {
- "personId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "status": "NONE"
}
], - "profile": "NONE"
}
}Submit the profile for review. Validates completeness (required fields per accountType, cross-person rules, required documents CLEAN, required agreements accepted) and moves the profile to SUBMITTED, triggering watchlist screening. Returns 400 with the missing items when not ready.
| payorId required | string <uuid> The account owner Payor ID |
{- "missingFields": [
- "registeredName",
- "taxId",
- "persons.controlPerson"
], - "pendingAgreements": [
- "csa",
- "mpa"
], - "ready": true,
- "pendingDocuments": [
- "W9",
- "PROOF_OF_SIGNATORIES"
], - "watchlist": {
- "persons": [
- {
- "personId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "status": "NONE"
}, - {
- "personId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "status": "NONE"
}
], - "profile": "NONE"
}
}Mint a presigned direct-upload URL for a KYC document belonging to an EXISTING user (the partner's userRef - 404 if the user is not in the calling partner's namespace). The document is linked to the user at mint time, server-side: PUT the file bytes to the URL (no auth header - the signature authorizes it; the content type must match exactly) and you are done - there is no reference or attach step, and a correctable submission is automatically sent back for verification. Uploading several documents? Set holdVerification=true on all but the last. Data corrections go through PUT on the user (which resubmits implicitly).
| userRef required | string [ 1 .. 100 ] characters The partner's id for the user this document belongs to. The user must already exist (404 otherwise) - the document is linked at mint time, server-side. |
| docType required | string Enum: "ID_FRONT" "ID_BACK" "SELFIE" "PROOF_OF_ADDRESS" "OTHER" What the document shows |
| contentType required | string Enum: "image/jpeg" "image/png" "application/pdf" The exact content type the upload will use (bound into the URL signature) |
| holdVerification | boolean Default: false By default, an upload to a correctable submission automatically sends it back for verification - upload and you are done. Set true to hold off (e.g. on all but the last upload of a multi-document correction). Uploads to submissions that are not correctable (approved, under review) always just link, silently. Data corrections go through PUT, which resubmits implicitly. |
{- "userRef": "userRef",
- "docType": "ID_FRONT",
- "contentType": "image/jpeg",
- "holdVerification": false
}{- "uploadUrl": "uploadUrl",
- "documentId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "expiresAt": "2000-01-23T04:56:07.000+00:00"
}Payors that are part of the same organization can be linked together in a hierarchical fashion
Your master account sits above every customer you create - your credential reads and writes on their behalf, and GET /v1/payorLinks lists the tree.
Payors can not access data of payors above them in the hierarchy
Contact Velo if you need to link payors in your organization
If the payor is set up as part of a hierarchy you can use this API to traverse the hierarchy
| descendantsOfPayor | string <uuid> The Payor ID from which to start the query to show all descendants |
| parentOfPayor | string <uuid> Query for the parent payor details for this payor id |
| fields | string List of additional Payor fields to include in the response for each Payor The values of payorId and payorName are always included for each Payor by default You can add fields to the response for each payor by including them in the fields parameter separated by commas The supported fields are any combination of: primaryContactEmail,kycState |
$ curl 'https://api.sandbox.velopayments.com/v1/payorLinks?descendantsOfPayor=0a818933-087d-47f2-ad83-2f986ed087eb' -i -X GET \ -H 'Authorization: Bearer 3387c417-464c-41a6-b25e-6630f0a06093' \ -H 'Content-Type: application/json'
{- "payors": [
- {
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "kycState": "kycState",
- "primaryContactEmail": "primaryContactEmail",
- "payorName": "payorName"
}, - {
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "kycState": "kycState",
- "primaryContactEmail": "primaryContactEmail",
- "payorName": "payorName"
}
], - "links": [
- {
- "toPayorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "linkId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "fromPayorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "linkType": "linkType"
}, - {
- "toPayorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "linkId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "fromPayorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "linkType": "linkType"
}
]
}APIs for initiating funding of source accounts from external sources and viewing balance updates
Instruct a funding request to transfer funds from the payor’s funding bank to the payor’s balance held within Velo
| sourceAccountId required | string <uuid> Source account id |
Body to included amount to be funded
| fundingAccountId required | string <uuid> The funding account id |
| amount required | integer <int64> [ 1 .. 9999999999 ] Amount to fund in minor units |
{- "fundingAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "amount": 800828191
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Get the funding accounts.
| payorId | string <uuid> |
| name | string The descriptive funding account name |
| countryCode | string Example: countryCode=US The 2 letter ISO 3166-1 country code (upper case) |
| currency | string Example: currency=USD The ISO 4217 currency code |
| type | string (FundingAccountTypeV2) Example: type=FBO The type of funding account. |
| page | integer <int32> Default: 1 Page number. Default is 1. |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
| sort | string[a-zA-Z]+[:desc|:asc] Default: "accountName:asc" List of sort fields (e.g. ?sort=accountName:asc,name:asc) Default is accountName:asc The supported sort fields are - accountName, name. |
| sensitive | boolean Default: false |
{- "links": [
], - "page": {
- "numberOfElements": 1,
- "totalPages": 2,
- "pageSize": 25,
- "page": 1,
- "totalElements": 1
}, - "content": [
- {
- "routingNumber": 12345678,
- "archived": true,
- "accountName": "Payor Corp",
- "countryCode": "US",
- "name": "My Funding Account",
- "currency": "USD",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "accountNumber": "7001001234",
- "type": "FBO"
}, - {
- "routingNumber": 12345678,
- "archived": true,
- "accountName": "Payor Corp",
- "countryCode": "US",
- "name": "My Funding Account",
- "currency": "USD",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "accountNumber": "7001001234",
- "type": "FBO"
}
]
}Get Funding Account by ID
| fundingAccountId required | string <uuid> |
| sensitive | boolean Default: false |
{- "routingNumber": 12345678,
- "archived": true,
- "accountName": "Payor Corp",
- "countryCode": "US",
- "name": "My Funding Account",
- "currency": "USD",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "accountNumber": "7001001234",
- "type": "FBO"
}Get funding audit deltas for a payor
| payorId required | string <uuid> |
| updatedSince required | string <date-time> |
| page | integer <int32> Default: 1 Page number. Default is 1. |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
{- "links": [
- {
- "rel": "rel",
- "href": "href"
}, - {
- "rel": "rel",
- "href": "href"
}
], - "page": {
- "numberOfElements": 0,
- "totalPages": 1,
- "pageSize": 5,
- "page": 5,
- "totalElements": 6
}, - "content": [
- {
- "amount": 2,
- "fundingId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "currency": "USD",
- "status": "status"
}, - {
- "amount": 2,
- "fundingId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "currency": "USD",
- "status": "status"
}
]
}Get Funding by Id
| fundingId required | string <uuid> |
{- "physicalAccountName": "physicalAccountName",
- "allocationDate": "2000-01-23T04:56:07.000+00:00",
- "reason": "reason",
- "amount": 0,
- "sourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "fundingId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "fundingAccountType": "FBO",
- "detectedFundingRef": "detectedFundingRef",
- "allocationType": "allocationType",
- "hiddenDate": "2000-01-23T04:56:07.000+00:00",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "currency": "USD",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "text": "text",
- "allocatedAt": "2000-01-23T04:56:07.000+00:00",
- "status": "ALLOCATED"
}Source Accounts are where a customer's funds are held on the platform - balances, funding, trading and withdrawals all operate against them. A customer typically holds one per currency.
List source accounts.
| physicalAccountName | string Physical Account Name |
| physicalAccountId | string <uuid> The physical account ID |
| payorId | string <uuid> The account owner Payor ID |
| fundingAccountId | string <uuid> The funding account ID |
| includeUserDeleted | string <boolean> A filter for retrieving both active accounts and user deleted ones |
| type | string (SourceAccountTypeV3) The type of source account. |
| page | integer <int32> Default: 1 Page number. Default is 1. |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
| sort | string[fundingRef|name|balance]+[:desc|:asc] Default: "fundingRef:asc" List of sort fields e.g. ?sort=name:asc Default is name:asc The supported sort fields are - fundingRef, name, balance |
$ curl 'https://api.sandbox.velopayments.com/v3/sourceAccounts?payorId=a2967711-df07-41e5-b5ea-f563088911c6' -i -X GET \ -H 'Authorization: Bearer 757a7dbf-2afb-45ec-877c-2aa3857c8e08'
{- "links": [
], - "page": {
- "numberOfElements": 12,
- "totalPages": 2,
- "pageSize": 25,
- "page": 1,
- "totalElements": 33
}, - "content": [
- {
- "physicalAccountName": "VELO_FBO_MYBANKA_USD",
- "country": "US",
- "userDeleted": true,
- "type": "FBO",
- "deletedAt": "2021-01-27T10:08:25.701Z",
- "fundingRef": "a1b2c3d4",
- "deleted": true,
- "balance": 1203489,
- "pooled": true,
- "transmissionTypes": [
- "ACH",
- "SAME_DAY_ACH"
], - "name": "MyAccountName",
- "customerId": "Joe Customer",
- "physicalAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "autoTopUpConfig": {
- "targetBalance": 300000,
- "fundingAccountId": "640ab1bd-8a6a-4603-a83a-1edbc3ed5689",
- "minBalance": 10000,
- "enabled": true
}, - "currency": "USD",
- "railsId": "BOA_RAIL",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "notifications": {
- "minimumBalance": 120000
}
}, - {
- "physicalAccountName": "VELO_FBO_MYBANKA_USD",
- "country": "US",
- "userDeleted": true,
- "type": "FBO",
- "deletedAt": "2021-01-27T10:08:25.701Z",
- "fundingRef": "a1b2c3d4",
- "deleted": true,
- "balance": 1203489,
- "pooled": true,
- "transmissionTypes": [
- "ACH",
- "SAME_DAY_ACH"
], - "name": "MyAccountName",
- "customerId": "Joe Customer",
- "physicalAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "autoTopUpConfig": {
- "targetBalance": 300000,
- "fundingAccountId": "640ab1bd-8a6a-4603-a83a-1edbc3ed5689",
- "minBalance": 10000,
- "enabled": true
}, - "currency": "USD",
- "railsId": "BOA_RAIL",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "notifications": {
- "minimumBalance": 120000
}
}
]
}Get details about given source account.
| sourceAccountId required | string <uuid> Source account id |
$ curl 'https://api.sandbox.velopayments.com/v3/sourceAccounts/126895a8-ba3d-44e8-9b34-84ee579cee7a' -i -X GET \ -H 'Authorization: Bearer a016f840-dafc-4b10-95f5-70ecc75a02d1'
{- "physicalAccountName": "VELO_FBO_MYBANKA_USD",
- "country": "US",
- "userDeleted": true,
- "type": "FBO",
- "deletedAt": "2021-01-27T10:08:25.701Z",
- "fundingRef": "a1b2c3d4",
- "deleted": true,
- "balance": 1203489,
- "pooled": true,
- "transmissionTypes": [
- "ACH",
- "SAME_DAY_ACH"
], - "name": "MyAccountName",
- "customerId": "Joe Customer",
- "physicalAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "autoTopUpConfig": {
- "targetBalance": 300000,
- "fundingAccountId": "640ab1bd-8a6a-4603-a83a-1edbc3ed5689",
- "minBalance": 10000,
- "enabled": true
}, - "currency": "USD",
- "railsId": "BOA_RAIL",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "notifications": {
- "minimumBalance": 120000
}
}Transfer funds between source accounts for a Payor. The 'from' source account is identified in the URL, and is the account which will be debited. The 'to' (destination) source account is in the body, and is the account which will be credited. Both source accounts must belong to the same Payor. There must be sufficient balance in the 'from' source account, otherwise the transfer attempt will fail.
| sourceAccountId required | string <uuid> The 'from' source account id, which will be debited |
Body
| toSourceAccountId required | string <uuid> The 'to' source account id, which will be credited |
| amount required | integer <int64> [ 1 .. 9999999999 ] Amount to transfer, in minor units |
| currency required | string (ISO Currency Code) = 3 characters ^[A-Z]{3}$ Valid ISO 4217 3 letter currency code. See the ISO specification for details. |
{- "amount": 800828191,
- "currency": "USD",
- "toSourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91"
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Set notifications for a given source account
If the balance falls below the amount set in the request an email notification will be sent to the email address registered in the payor profile
| sourceAccountId required | string <uuid> Source account id |
Body to included minimum balance to set
| minimumBalance required | integer <int64> [ 0 .. 9999999999 ] Amount to set as minimum balance for notifications in minor units |
{- "minimumBalance": 10000000
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Transactions are linked to a specific Source Account and allow a payor to logically separate funds
Get list of Transactions
| payorId | string |
| transactionReference | string |
| page | integer <int32> Default: 1 Page number. Default is 1. |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
| sort | string Default: "createdAt:asc" |
{- "links": [
- {
- "rel": "rel",
- "href": "href"
}, - {
- "rel": "rel",
- "href": "href"
}
], - "page": {
- "numberOfElements": 0,
- "totalPages": 1,
- "pageSize": 5,
- "page": 5,
- "totalElements": 6
}, - "content": [
- {
- "createdAt": "2021-01-27T10:08:25.701Z",
- "sourceAccountId": "7faf83a7-77e2-40bc-9e78-7d18fa2bb63e",
- "transactionMetadata": {
- "key": "any_value"
}, - "balance": 800828190,
- "transactionReference": "myInvoiceNumber-1234567890",
- "currency": "USD",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "transactionId": "4d88e559-d057-45b1-8d8b-b9ccc06f4503",
- "transactionShortCode": "T1234ABC",
- "sourceAccountName": "Payor_FOO_USD_Account"
}, - {
- "createdAt": "2021-01-27T10:08:25.701Z",
- "sourceAccountId": "7faf83a7-77e2-40bc-9e78-7d18fa2bb63e",
- "transactionMetadata": {
- "key": "any_value"
}, - "balance": 800828190,
- "transactionReference": "myInvoiceNumber-1234567890",
- "currency": "USD",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "transactionId": "4d88e559-d057-45b1-8d8b-b9ccc06f4503",
- "transactionShortCode": "T1234ABC",
- "sourceAccountName": "Payor_FOO_USD_Account"
}
]
}Create a new Transaction that can be funded
| payorId required | string <uuid> Indicates the Payor creating the Transaction and which matches the payorId on the provided source account |
| sourceAccountName required | string [ 3 .. 100 ] characters The name of the source account that the new Transaction will be associated with and any funding containing the transactionShortCode will credit. |
| transactionReference required | string [ 6 .. 100 ] characters The payors own reference for the transaction that can later be used for querying and retrieval. |
object Optional metadata that will be attached to the created transaction and can that can be retrieved later.| The total length of all the keys and values provided in the metadata must be no more than 4000 chars. |
{- "transactionMetadata": {
- "key": "any_value"
}, - "transactionReference": "myInvoiceNumber-1234567890",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "sourceAccountName": "Payor_FOO_USD_Account"
}{- "transactionId": "4d88e559-d057-45b1-8d8b-b9ccc06f4503",
- "transactionShortCode": "T1234ABC"
}Get Transaction by Id
| transactionId required | string <uuid> |
{- "createdAt": "2021-01-27T10:08:25.701Z",
- "sourceAccountId": "7faf83a7-77e2-40bc-9e78-7d18fa2bb63e",
- "transactionMetadata": {
- "key": "any_value"
}, - "balance": 800828190,
- "transactionReference": "myInvoiceNumber-1234567890",
- "currency": "USD",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "transactionId": "4d88e559-d057-45b1-8d8b-b9ccc06f4503",
- "transactionShortCode": "T1234ABC",
- "sourceAccountName": "Payor_FOO_USD_Account"
}Register a webhook on each customer's payor to be notified of changes - the same URL for every customer works, and the payorId in each notification tells you who it concerns.
Notifications are wake-up messages: they say what changed and carry ids, and the corresponding GET is the authoritative state. sequenceNumber is per payor. Delivery is at-least-once with exponential backoff - handle duplicates by sequenceNumber.
Categories: "verification" (customer identity and destination verification - including re-verification long after onboarding), "funding" (deposits), "trading" (trade status), "payment" (self transfer status), "system" (ping).
The webhook notifications that are sent to the payor's configured webhook endpoint URL
| apiVersion required | string The API version of the notification schema |
| sequenceNumber required | integer <int64> This is a payor specific sequence number starting at 1 for the first notification sent |
| category required | string The category that the notification relates to. One of "verification", "funding", "trading", "payment", "debit" or "system" |
| eventName required | string The name of event that led to this notification |
any One of the available set of source event payloads |
{- "apiVersion": "1",
- "sequenceNumber": 1234,
- "category": "verification",
- "eventName": "payment.accepted",
- "source": {
- "type": "payment_status_changed",
- "eventId": "270ab907-27ec-4b83-8028-0ff432bbdec4",
- "createdAt": "2020-06-18T15:09:42Z",
- "paymentId": "cbd9280f-8fde-4190-b014-979d88f3ec54",
- "payoutPayorIds": {
- "submittingPayorId": "ac207f97-663c-4429-9d57-ba5b35d6672d",
- "payoutFromPayorId": "ac207f97-663c-4429-9d57-ba5b35d6672d",
- "payoutToPayorId": "ac207f97-663c-4429-9d57-ba5b35d6672d"
}, - "payorPaymentId": "ourpayment-id12345",
- "status": "ACCEPTED"
}
}List the details about the webhooks for the given payor.
| page | integer <int32> Default: 1 Page number. Default is 1. |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
| payorId required | string <uuid> The Payor ID |
$ curl 'https://api.sandbox.velopayments.com/v1/webhooks?payorId=a2967711-df07-41e5-b5ea-f563088911c6' -i -X GET \ -H 'Authorization: Bearer 757a7dbf-2afb-45ec-877c-2aa3857c8e08'
{- "links": [
- {
- "rel": "first",
}, - {
- "rel": "first",
}
], - "page": {
- "numberOfElements": 10,
- "totalPages": 10,
- "pageSize": 10,
- "page": 10,
- "totalElements": 10
}, - "content": [
- {
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "authorizationHeader": "authorizationHeader",
- "categories": [
- null,
- null
], - "webhookUrl": "webhookUrl",
- "enabled": true
}, - {
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "authorizationHeader": "authorizationHeader",
- "categories": [
- null,
- null
], - "webhookUrl": "webhookUrl",
- "enabled": true
}
]
}Create Webhook
| payorId required | string <uuid> |
| webhookUrl required | string [ 6 .. 2000 ] characters the webhook URL to use. |
| authorizationHeader | string [ 4 .. 1000 ] characters .* the authorization header to include with the notification. |
| enabled required | boolean whether the webhook is enabled. |
| categories | Array of strings (Category) Items Enum: "payment" "payee" "debit" "funding" the categories to enable. |
{- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "authorizationHeader": "authorizationHeader",
- "categories": [
- null,
- null
], - "webhookUrl": "webhookUrl",
- "enabled": true
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Get details about the given webhook.
| webhookId required | string <uuid> Webhook id |
$ curl 'https://api.sandbox.velopayments.com/v1/webhooks/126895a8-ba3d-44e8-9b34-84ee579cee7a' -i -X GET \ -H 'Authorization: Bearer a016f840-dafc-4b10-95f5-70ecc75a02d1'
{- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "authorizationHeader": "authorizationHeader",
- "categories": [
- null,
- null
], - "webhookUrl": "webhookUrl",
- "enabled": true
}Update Webhook
| webhookId required | string <uuid> Webhook id |
| webhookUrl | string [ 6 .. 2000 ] characters the webhook URL to use. |
| authorizationHeader | string or null [ 4 .. 1000 ] characters .* the authorization header to include with the notification. |
| enabled | boolean whether the webhook is enabled. |
| categories | Array of strings or null (Category) Enum: "payment" "payee" "debit" "funding" The notification categories to enable. |
{- "authorizationHeader": "authorizationHeader",
- "categories": [
- null,
- null
], - "webhookUrl": "webhookUrl",
- "enabled": true
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Currency trades between a customer's own source accounts - quote, execute, track.
A quote carries the rate, itemized fee lines and the net amount the destination account will receive. Executing is idempotent on your own tradeRef. Amounts are integers in minor units: USD in cents, USDC in micro-USDC (6 implied decimals).
Request an executable quote for a trade between two of the payor's source accounts. The quote carries the rate, itemized fee lines and the net amount the destination account will receive, and is executable until it expires (seconds-scale validity).
Amounts are integers in the minor units of their currency: USD in cents, USDC in micro-USDC (6 implied decimals).
| payorId required | string <uuid> The account owner Payor ID |
The trade to quote
| sourceAccountId required | string <uuid> The source account the trade spends from |
| destSourceAccountId required | string <uuid> The source account the trade proceeds land in |
| fixedSide required | string (FixedSide) Enum: "SOURCE" "DESTINATION" Which side of the trade the amount fixes. SOURCE spends exactly the given amount and the destination amount is discovered at execution; DESTINATION receives at least the given amount and the source amount is solved backwards from the quote. |
| amount required | integer <int64> >= 1 The amount being fixed, in minor units of the fixed side's currency (USD cents, or micro-USDC) |
| currency required | string (TradeCurrency) Enum: "USD" "USDC" A tradable currency. Amounts for a currency are always expressed in its minor units: USD in cents (2 implied decimals), USDC in micro-USDC (6 implied decimals). |
{- "sourceAccountId": "7faf83a7-77e2-40bc-9e78-7d18fa2bb63e",
- "amount": 10000000,
- "fixedSide": "SOURCE",
- "currency": "USDC",
- "destSourceAccountId": "4d88e559-d057-45b1-8d8b-b9ccc06f4503"
}{- "destAmount": 99890400,
- "rate": "0.998904",
- "destCurrency": "USDC",
- "netDestAmount": 98892496,
- "sourceCurrency": "USDC",
- "sourceAmount": 10000000,
- "quoteId": "9c34401d-b432-4b1b-8c2b-5e3e9d1a4c11",
- "feeLines": [
- {
- "amount": 997600,
- "description": "On/off-ramp fee (60bps at or above USD 10,000 notional)",
- "currency": "USDC",
- "type": "RAMP_FEE"
}, - {
- "amount": 997600,
- "description": "On/off-ramp fee (60bps at or above USD 10,000 notional)",
- "currency": "USDC",
- "type": "RAMP_FEE"
}
], - "expiresAt": "2026-08-13T10:08:40.001Z"
}List the payor's trades, newest first
| payorId required | string <uuid> The account owner Payor ID |
| status | string (TradeStatus) Enum: "PENDING" "EXECUTING" "COMPLETED" "FAILED" "CANCELED" Example: status=COMPLETED Filter by trade status |
| page | integer <int32> Default: 1 Page number. Default is 1. |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
{- "links": [
- "{}",
- "{}"
], - "page": {
- "numberOfElements": 10,
- "totalPages": 10,
- "pageSize": 10,
- "page": 10,
- "totalElements": 10
}, - "content": [
- {
- "quotedRate": "0.998904",
- "sourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "completedAt": "2000-01-23T04:56:07.000+00:00",
- "netDestAmount": 98893189,
- "tradeRef": "order-20260813-0042",
- "sourceCurrency": "USDC",
- "destSourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "destAmount": 99891100,
- "destCurrency": "USDC",
- "executedRate": "0.998911",
- "failureReason": "failureReason",
- "sourceAmount": 10000000,
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "tradeId": "2f0a1b7e-9d64-4b0a-a2ee-6f0c3b6f7d21",
- "feeLines": [
- {
- "amount": 997600,
- "description": "On/off-ramp fee (60bps at or above USD 10,000 notional)",
- "currency": "USDC",
- "type": "RAMP_FEE"
}, - {
- "amount": 997600,
- "description": "On/off-ramp fee (60bps at or above USD 10,000 notional)",
- "currency": "USDC",
- "type": "RAMP_FEE"
}
], - "status": "COMPLETED"
}, - {
- "quotedRate": "0.998904",
- "sourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "completedAt": "2000-01-23T04:56:07.000+00:00",
- "netDestAmount": 98893189,
- "tradeRef": "order-20260813-0042",
- "sourceCurrency": "USDC",
- "destSourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "destAmount": 99891100,
- "destCurrency": "USDC",
- "executedRate": "0.998911",
- "failureReason": "failureReason",
- "sourceAmount": 10000000,
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "tradeId": "2f0a1b7e-9d64-4b0a-a2ee-6f0c3b6f7d21",
- "feeLines": [
- {
- "amount": 997600,
- "description": "On/off-ramp fee (60bps at or above USD 10,000 notional)",
- "currency": "USDC",
- "type": "RAMP_FEE"
}, - {
- "amount": 997600,
- "description": "On/off-ramp fee (60bps at or above USD 10,000 notional)",
- "currency": "USDC",
- "type": "RAMP_FEE"
}
], - "status": "COMPLETED"
}
]
}Execute a quoted trade between two of the payor's source accounts. Accepted trades execute asynchronously; the Location header points at the trade to poll, and a webhook can announce the status change.
tradeRef is your own reference and the idempotency key: submitting
the same tradeRef again returns the existing trade's Location instead of creating
a duplicate.
| payorId required | string <uuid> The account owner Payor ID |
The trade to execute
| tradeRef required | string [ 1 .. 128 ] characters Your own reference for this trade - the idempotency key |
| quoteId required | string <uuid> The quote being executed. An expired quote is rejected. |
| sourceAccountId required | string <uuid> |
| destSourceAccountId required | string <uuid> |
| fixedSide required | string (FixedSide) Enum: "SOURCE" "DESTINATION" Which side of the trade the amount fixes. SOURCE spends exactly the given amount and the destination amount is discovered at execution; DESTINATION receives at least the given amount and the source amount is solved backwards from the quote. |
| amount required | integer <int64> >= 1 The amount being fixed, in minor units of the fixed side's currency (USD cents, or micro-USDC) |
| currency required | string (TradeCurrency) Enum: "USD" "USDC" A tradable currency. Amounts for a currency are always expressed in its minor units: USD in cents (2 implied decimals), USDC in micro-USDC (6 implied decimals). |
{- "sourceAccountId": "7faf83a7-77e2-40bc-9e78-7d18fa2bb63e",
- "amount": 10000000,
- "fixedSide": "SOURCE",
- "tradeRef": "order-20260813-0042",
- "currency": "USDC",
- "quoteId": "9c34401d-b432-4b1b-8c2b-5e3e9d1a4c11",
- "destSourceAccountId": "4d88e559-d057-45b1-8d8b-b9ccc06f4503"
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Get a single trade. Executed values (rate, amounts, fees) are final once the status is COMPLETED.
| payorId required | string <uuid> The account owner Payor ID |
| tradeId required | string <uuid> The Trade ID |
{- "quotedRate": "0.998904",
- "sourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "completedAt": "2000-01-23T04:56:07.000+00:00",
- "netDestAmount": 98893189,
- "tradeRef": "order-20260813-0042",
- "sourceCurrency": "USDC",
- "destSourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "destAmount": 99891100,
- "destCurrency": "USDC",
- "executedRate": "0.998911",
- "failureReason": "failureReason",
- "sourceAmount": 10000000,
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "tradeId": "2f0a1b7e-9d64-4b0a-a2ee-6f0c3b6f7d21",
- "feeLines": [
- {
- "amount": 997600,
- "description": "On/off-ramp fee (60bps at or above USD 10,000 notional)",
- "currency": "USDC",
- "type": "RAMP_FEE"
}, - {
- "amount": 997600,
- "description": "On/off-ramp fee (60bps at or above USD 10,000 notional)",
- "currency": "USDC",
- "type": "RAMP_FEE"
}
], - "status": "COMPLETED"
}Payor-owned withdrawal destinations - a bank account or a wallet the customer controls. Destinations are verified before they can receive a transfer.
List the payor's self transfer destinations. Bank account and routing numbers are always masked.
| payorId required | string <uuid> The payor id |
{- "selfTransferDestinations": [
- {
- "walletNetwork": "ETHEREUM",
- "kind": "OWN_BANK",
- "verifiedAt": "2000-01-23T04:56:07.000+00:00",
- "bankOwnerName": "bankOwnerName",
- "bankName": "bankName",
- "bankCountry": "USA",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "statusReason": "statusReason",
- "bankRoutingNumber": "XXXXX6789",
- "currency": "USDC",
- "bankAccountNumber": "XXXXXX6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "walletAddress": "walletAddress",
- "walletLabel": "walletLabel",
- "status": "PENDING_VERIFICATION"
}, - {
- "walletNetwork": "ETHEREUM",
- "kind": "OWN_BANK",
- "verifiedAt": "2000-01-23T04:56:07.000+00:00",
- "bankOwnerName": "bankOwnerName",
- "bankName": "bankName",
- "bankCountry": "USA",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "statusReason": "statusReason",
- "bankRoutingNumber": "XXXXX6789",
- "currency": "USDC",
- "bankAccountNumber": "XXXXXX6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "walletAddress": "walletAddress",
- "walletLabel": "walletLabel",
- "status": "PENDING_VERIFICATION"
}
]
}Create a payor-owned destination that self transfers can pay to. Destinations are created PENDING_VERIFICATION and verified by the rails service before they can receive a transfer.
| payorId required | string <uuid> The payor id |
| kind required | string [ 1 .. 24 ] characters The kind of destination. One of the following values: OWN_BANK, OWN_UNMANAGED_WALLET |
| currency required | string (Currency Ticker) [ 2 .. 6 ] characters ^[A-Z]{2,6}$ Standard currency ticker - ISO 4217 for fiat (USD), the common ticker for digital assets (USDC). Amounts for a currency are integers in its minor units. |
| bankAccountNumber | string [ 4 .. 17 ] characters ^\d{4,17}$ Required for kind OWN_BANK. 4 to 17 digits. |
| bankRoutingNumber | string = 9 characters ^\d{9}$ Required for kind OWN_BANK. 9 digits, must pass the ABA check digit validation. |
| bankName | string [ 1 .. 255 ] characters Required for kind OWN_BANK. |
| bankOwnerName | string [ 1 .. 255 ] characters Required for kind OWN_BANK. Must be the payor's registered name or a principal's name. |
| bankCountry | string = 3 characters Required for kind OWN_BANK. ISO 3166-1 alpha-3 country code. |
| walletAddress | string [ 1 .. 128 ] characters Required for kind OWN_UNMANAGED_WALLET. Format is validated per wallet network. |
| walletNetwork | string [ 1 .. 32 ] characters Required for kind OWN_UNMANAGED_WALLET. Must be one of the configured wallet networks, e.g. ETHEREUM, BASE, ARBITRUM, POLYGON, SOLANA. |
| walletLabel | string [ 1 .. 100 ] characters Optional display label for the wallet. |
{- "walletNetwork": "ETHEREUM",
- "kind": "OWN_BANK",
- "bankRoutingNumber": "bankRoutingNumber",
- "bankOwnerName": "bankOwnerName",
- "currency": "USDC",
- "bankAccountNumber": "bankAccountNumber",
- "bankName": "bankName",
- "walletAddress": "walletAddress",
- "bankCountry": "USA",
- "walletLabel": "walletLabel"
}{- "walletNetwork": "ETHEREUM",
- "kind": "OWN_BANK",
- "verifiedAt": "2000-01-23T04:56:07.000+00:00",
- "bankOwnerName": "bankOwnerName",
- "bankName": "bankName",
- "bankCountry": "USA",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "statusReason": "statusReason",
- "bankRoutingNumber": "XXXXX6789",
- "currency": "USDC",
- "bankAccountNumber": "XXXXXX6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "walletAddress": "walletAddress",
- "walletLabel": "walletLabel",
- "status": "PENDING_VERIFICATION"
}Delete a self transfer destination by id.
| payorId required | string <uuid> The payor id |
| selfTransferDestinationId required | string <uuid> The self transfer destination id |
{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Get a single self transfer destination. Bank account and routing numbers are always masked.
| payorId required | string <uuid> The payor id |
| selfTransferDestinationId required | string <uuid> The self transfer destination id |
{- "walletNetwork": "ETHEREUM",
- "kind": "OWN_BANK",
- "verifiedAt": "2000-01-23T04:56:07.000+00:00",
- "bankOwnerName": "bankOwnerName",
- "bankName": "bankName",
- "bankCountry": "USA",
- "createdAt": "2000-01-23T04:56:07.000+00:00",
- "statusReason": "statusReason",
- "bankRoutingNumber": "XXXXX6789",
- "currency": "USDC",
- "bankAccountNumber": "XXXXXX6789",
- "id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "walletAddress": "walletAddress",
- "walletLabel": "walletLabel",
- "status": "PENDING_VERIFICATION"
}Move a customer's own funds out of the platform to one of their verified destinations: USD to their own bank account (kind OWN_BANK), or USDC to their own wallet (kind OWN_UNMANAGED_WALLET). The same API covers the full exit - a customer cashing out trades back to USD and self-transfers to their bank.
Freshly traded proceeds may briefly be settling before they are withdrawable; a transfer against settling funds queues rather than fails.
List the payor's self transfers with a status projection of the underlying payment
| payorId required | string <uuid> The id (UUID) of the Payor |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
| page | integer <int32> Default: 1 Page number. Default is 1. |
$ curl 'https://api.sandbox.velopayments.com/v1/payors/1eeb5f9b-9a27-46ea-bd83-b9b2ebc9e5b3/selfTransfers' -i -X GET \ -H 'Authorization: Bearer 63e4d691-847b-46b5-893d-fd15c54dd4bf'
{- "links": [
- {
- "rel": "rel",
- "href": "href"
}, - {
- "rel": "rel",
- "href": "href"
}
], - "page": {
- "numberOfElements": 0,
- "totalPages": 1,
- "pageSize": 5,
- "page": 5,
- "totalElements": 6
}, - "content": [
- {
- "selfTransferId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "amount": 12345,
- "paymentId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "memo": "memo",
- "currency": "USDC",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "destinationId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "fromSourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "status": "PENDING"
}, - {
- "selfTransferId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "amount": 12345,
- "paymentId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "memo": "memo",
- "currency": "USDC",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "destinationId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "fromSourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "status": "PENDING"
}
]
}Move funds from one of the payor's own source accounts to one of the payor's verified self-transfer destinations (own bank account or own whitelisted wallet).
Creates the transfer and returns a Location header linking the created resource. There is no payee - the verified destination takes that place.
**NOTE:** amount values must be in 'minor units' format with no decimal places
| payorId required | string <uuid> The id (UUID) of the Payor |
| fromSourceAccountId required | string <uuid> The id of the payor's own source account to debit. Must belong to the payor and be on a rails that supports self transfers. |
| destinationId required | string <uuid> The id of the payor's self-transfer destination (funding-manager). Must belong to the payor and be VERIFIED. |
| amount required | integer <int64> >= 1 Amount to transfer in minor units of the currency with no decimal places |
| currency required | string (Currency Ticker) [ 2 .. 6 ] characters ^[A-Z]{2,6}$ Standard currency ticker - ISO 4217 for fiat (USD), the common ticker for digital assets (USDC). Amounts for a currency are integers in its minor units. |
| memo | string <= 40 characters Optional memo for the transfer |
{- "amount": 12345,
- "memo": "memo",
- "currency": "USDC",
- "destinationId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "fromSourceAccountId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91"
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Payment Audit Service APIs allow you to see the history of fundings into your source accounts.
Get a list of Fundings for a payor.
| payorId required | string <uuid> The account owner Payor ID |
| sourceAccountName | string The source account name |
| page | integer <int32> Default: 1 Page number. Default is 1. |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
| sort | string List of sort fields. Example: |
$ curl 'https://api.sandbox.velopayments.com/v4/paymentaudit/fundings?payorId=2a5d8af2-a1ed-4d7f-b9a7-ebe4b333be5a' -i -X GET \ -H 'Authorization: Bearer 3667f994-7d41-4d20-990d-b79fa720e56b'
{- "links": [
], - "page": {
- "numberOfElements": 12,
- "totalPages": 2,
- "pageSize": 25,
- "page": 1,
- "totalElements": 33
}, - "content": [
- {
- "dateTime": "2000-01-23T04:56:07.000+00:00",
- "fundingAccountName": "fundingAccountName",
- "amount": 120000,
- "fundingType": "fundingType",
- "transactionReference": "transactionReference",
- "currency": "USD",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "topupType": "topupType",
- "events": [
- {
- "principal": "principal",
- "eventId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "eventDateTime": "2000-01-23T04:56:07.000+00:00",
- "fundingEventType": "fundingEventType"
}, - {
- "principal": "principal",
- "eventId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "eventDateTime": "2000-01-23T04:56:07.000+00:00",
- "fundingEventType": "fundingEventType"
}
], - "transactionId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "status": "status",
- "sourceAccountName": "sourceAccountName"
}, - {
- "dateTime": "2000-01-23T04:56:07.000+00:00",
- "fundingAccountName": "fundingAccountName",
- "amount": 120000,
- "fundingType": "fundingType",
- "transactionReference": "transactionReference",
- "currency": "USD",
- "payorId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "topupType": "topupType",
- "events": [
- {
- "principal": "principal",
- "eventId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "eventDateTime": "2000-01-23T04:56:07.000+00:00",
- "fundingEventType": "fundingEventType"
}, - {
- "principal": "principal",
- "eventId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "eventDateTime": "2000-01-23T04:56:07.000+00:00",
- "fundingEventType": "fundingEventType"
}
], - "transactionId": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
- "status": "status",
- "sourceAccountName": "sourceAccountName"
}
]
}Use this endpoint to obtain an access token for calling Velo Payments APIs.
You need your API key and API secret issued by Velo
To login and get an access token the API key and API secret must be Base64 encoded by concatenating them with a colon between them
e.g. Given an ApiKey: 44a9537d-d55d-4b47-8082-14061c2bcdd8 and ApiSecret: c396b26b-137a-44fd-87f5-34631f8fd529
Using a Base64 encode function Base64Encoder().encode("44a9537d-d55d-4b47-8082-14061c2bcdd8:c396b26b-137a-44fd-87f5-34631f8fd529")
Included as a Basic Authorization header: -H "Authorization: Basic NDRhOTUzN2QtZDU1ZC00YjQ3LTgwODItMTQwNjFjMmJjZGQ4OmMzOTZiMjZiLTEzN2EtNDRmZC04N2Y1LTM0NjMxZjhmZDUyOQ=="
| grant_type | string Default: "client_credentials" OAuth grant type. Should use 'client_credentials' |
{- "access_token": "IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
- "refresh_token": "IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
- "scope": "example_scope",
- "token_type": "bearer",
- "expires_in": 1799,
- "entityIds": [
- "entityIds",
- "entityIds"
]
}Given a valid access token in the header then log out the authenticated user or client
Will revoke the token
$ curl 'https://api.sandbox.velopayments.com/v1/logout' -i -X POST \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer 93560bbb-5e79-492a-97b5-1ffbdf1cfeb8'
{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 401
}Get a paginated response listing the Users
| type | string (UserType) Enum: "BACKOFFICE" "PAYOR" "PAYEE" Example: type=PAYOR The Type of the User. |
| status | string (UserStatus) Enum: "ENABLED" "DISABLED" "PENDING" Example: status=ENABLED The status of the User. |
| entityId | string <uuid> The entityId of the User. |
| payeeType | string (PayeeType) Enum: "COMPANY" "INDIVIDUAL" Example: payeeType=COMPANY The Type of the Payee entity. Either COMPANY or INDIVIDUAL. |
| page | integer <int32> Default: 1 Page number. Default is 1. |
| pageSize | integer <int32> [ 1 .. 100 ] Default: 25 The number of results to return in a page |
| sort | string[a-zA-Z]+[:desc|:asc] Default: "email:asc" List of sort fields (e.g. ?sort=email:asc,lastName:asc) Default is email:asc 'name' The supported sort fields are - email, lastNmae. |
$ curl 'https://api.sandbox.velopayments.com/v2/users?pageSize=2&page=8&status=DISABLED' -i -X GET \ -H 'Authorization: Bearer 6dd5e976-e329-462f-bd6b-25d463cf02fd' \ -H 'Content-Type: application/json'
{- "links": [
- {
- "rel": "first",
}, - {
- "rel": "first",
}
], - "page": {
- "numberOfElements": 12,
- "totalPages": 2,
- "pageSize": 25,
- "page": 1,
- "totalElements": 33
}, - "content": [
- {
- "lastName": "Doe",
- "companyName": "Acme Corp",
- "roles": [
- "payor.admin"
], - "lockedOutTimestamp": "2000-01-23T04:56:07.000+00:00",
- "smsNumber": "11235555555",
- "entityId": "7fffa261-ac68-49e6-b605-d24a444d9206",
- "mfaStatus": "REGISTERED",
- "firstName": "John",
- "primaryContactNumber": "11235555555",
- "mfaType": "TOTP",
- "lockedOut": true,
- "id": "8bbf301c-948f-4445-b411-357eec53e441",
- "userType": "PAYOR",
- "email": "foo@example.com",
- "secondaryContactNumber": "11235555550",
- "status": "ENABLED"
}, - {
- "lastName": "Doe",
- "companyName": "Acme Corp",
- "roles": [
- "payor.admin"
], - "lockedOutTimestamp": "2000-01-23T04:56:07.000+00:00",
- "smsNumber": "11235555555",
- "entityId": "7fffa261-ac68-49e6-b605-d24a444d9206",
- "mfaStatus": "REGISTERED",
- "firstName": "John",
- "primaryContactNumber": "11235555555",
- "mfaType": "TOTP",
- "lockedOut": true,
- "id": "8bbf301c-948f-4445-b411-357eec53e441",
- "userType": "PAYOR",
- "email": "foo@example.com",
- "secondaryContactNumber": "11235555550",
- "status": "ENABLED"
}
]
}Delete User by Id.
| userId required | string <uuid> The UUID of the User. |
$ curl 'https://api.sandbox.velopayments.com/v2/users/d4ca564-f2ee-4725-97c2-7193a093f0f1' -i -X DELETE \ -H 'Authorization: Bearer 3387c417-464c-41a6-b25e-6630f0a06093' \ -H 'Content-Type: application/json'
{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 401
}Get a Single User by Id.
| userId required | string <uuid> The UUID of the User. |
$ curl 'https://api.sandbox.velopayments.com/v2/users/d4ca564-f2ee-4725-97c2-7193a093f0f1' -i -X GET \ -H 'Authorization: Bearer 3387c417-464c-41a6-b25e-6630f0a06093' \ -H 'Content-Type: application/json'
{- "lastName": "Doe",
- "companyName": "Acme Corp",
- "roles": [
- "payor.admin"
], - "lockedOutTimestamp": "2000-01-23T04:56:07.000+00:00",
- "smsNumber": "11235555555",
- "entityId": "7fffa261-ac68-49e6-b605-d24a444d9206",
- "mfaStatus": "REGISTERED",
- "firstName": "John",
- "primaryContactNumber": "11235555555",
- "mfaType": "TOTP",
- "lockedOut": true,
- "id": "8bbf301c-948f-4445-b411-357eec53e441",
- "userType": "PAYOR",
- "email": "foo@example.com",
- "secondaryContactNumber": "11235555550",
- "status": "ENABLED"
}If a user is enabled this endpoint will disable them
The invoker must have the appropriate permission
A user cannot disable themself
When a user is disabled any active access tokens will be revoked and the user will not be able to log in
| userId required | string <uuid> The UUID of the User. |
$ curl 'https://api.sandbox.velopayments.com/v2/users/79a6fdaa-f4bb-47b7-9c1f-f6fd99c156a0/disable' -i -X POST \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer 93560bbb-5e79-492a-97b5-1ffbdf1cfeb8'
{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}If a user has been disabled this endpoints will enable them
The invoker must have the appropriate permission
A user cannot enable themself
If the user is a payor user and the payor is disabled this operation is not allowed
If enabling a payor user would breach the limit for master admin payor users the request will be rejected
| userId required | string <uuid> The UUID of the User. |
$ curl 'https://api.sandbox.velopayments.com/v2/users/79a6fdaa-f4bb-47b7-9c1f-f6fd99c156a0/enable' -i -X POST \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer 93560bbb-5e79-492a-97b5-1ffbdf1cfeb8'
{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Create a User and invite them to the system
Details of User to invite
| email required | string <email> the email address of the invited user |
| mfaType required | string Enum: "SMS" "YUBIKEY" "TOTP" The MFA type that the user will use The type may be conditional on the role(s) the user has |
| smsNumber required | string^\+[1-9]\d{1,14}$ The phone number of a device that the user can receive sms messages on |
| primaryContactNumber required | string^\+[1-9]\d{1,14}$ The main contact number for the user |
| secondaryContactNumber | string or null^\+[1-9]\d{1,14}$ The secondary contact number for the user |
| roles required | Array of strings The role(s) for the user The role must exist The role can be a custom role or a system role but the invoker must have the permissions to assign the role System roles are: velo.backoffice.admin, velo.payor.master_admin, velo.payor.admin, velo.payor.support, velo.payee.admin, velo.payee.support |
| firstName | string [ 1 .. 128 ] characters |
| lastName | string [ 1 .. 128 ] characters |
| entityId | string or null <uuid> The payorId or payeeId or null if the user is a backoffice admin |
| userType | string Enum: "BACKOFFICE" "PAYOR" "PAYEE" Will default to PAYOR if not provided but entityId is provided |
| verificationCode | string or null = 6 characters Optional property that MUST be suppied when manually verifying a user The user's smsNumber is registered via a separate endpoint and an OTP sent to them |
{- "firstName": "John",
- "lastName": "Doe",
- "primaryContactNumber": "11235555555",
- "mfaType": "TOTP",
- "roles": [
- "velo.payor.admin"
], - "smsNumber": "11235555555",
- "entityId": "7fffa261-ac68-49e6-b605-d24a444d9206",
- "userType": "PAYEE",
- "email": "foo@example.com",
- "secondaryContactNumber": "11235555550",
- "verificationCode": "123456"
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Resend the specified token
The token to resend must already exist for the user
It will be revoked and a new one issued
| userId required | string <uuid> The UUID of the User. |
The type of token to resend
| tokenType required | string Enum: "INVITE_MFA_USER" "MFA_REGISTRATION" The type of the token to resend |
| verificationCode | string or null = 6 characters Optional property that MUST be suppied when manually verifying a user The user's smsNumber is registered via a separate endpoint and an OTP sent to them |
{- "tokenType": "INVITE_MFA_USER",
- "verificationCode": "123456"
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}Verification tokens allow users to complete authenitcation flows such as user invite, MFA registration and password reset
Tokens have an expiry and are one-time use only
Resend the specified token
The token to resend must already exist for the user
It will be revoked and a new one issued
| userId required | string <uuid> The UUID of the User. |
The type of token to resend
| tokenType required | string Enum: "INVITE_MFA_USER" "MFA_REGISTRATION" The type of the token to resend |
| verificationCode | string or null = 6 characters Optional property that MUST be suppied when manually verifying a user The user's smsNumber is registered via a separate endpoint and an OTP sent to them |
{- "tokenType": "INVITE_MFA_USER",
- "verificationCode": "123456"
}{- "errors": [
- {
- "errorMessage": "size must be between 0 and 10",
- "errorCode": "20110003",
- "localisationDetails": {
- "template": "size must be between {min} and {max}",
- "parameters": {
- "min": "0",
- "max": "10"
}
}, - "location": "firstName",
- "locationType": "requestBody",
- "reasonCode": "validationError",
- "errorData": {
- "description": "The rejected CSV rows",
- "content": { }
}
}
], - "correlationId": "ee53e01d-c078-43fd-abd4-47e92f4a06cf",
- "httpStatusCode": 400
}$ curl 'https://api.sandbox.velopayments.com/v2/currencies' -i -X GET
{- "currencies": [
- {
- "currency": "USD",
- "maxPaymentAmount": 100000
}, - {
- "currency": "USD",
- "maxPaymentAmount": 100000
}
]
}