Jeeves Payment API (1.0.0)

Quote FX, create payments idempotently, and track them through signed webhooks.

Lock an FX rate, create a payment against it, and follow it to a terminal status. Conventions, authentication and error handling are covered in the Jeeves Payment API Integration Guide.

Getting credentials: sandbox and production each need their own client credentials. Email support@tryjeeves.com to request them for either environment.

mTLS on every call: all requests — including POST /oauth/token — require your client certificate. The curl examples show the --cert/--key flags once, on the token call, and omit them elsewhere for brevity; add them to every request.

Looking for cards, boletos, transactions, or webhook subscriptions? Those live in the main API reference.

Download OpenAPI description
Overview
Languages
Servers
Sandbox
https://public-sandbox.tryjeeves.com/
Production
https://public-api.jeev.es/

Authentication

Exchange client credentials for a short-lived bearer token.

Operations

Accounts

The accounts you can fund payments from.

Operations

Beneficiaries

The people and businesses you pay, with their attached payment methods.

Operations

List beneficiaries

Request

List your beneficiaries, each with the payment methods attached to it.

Use paymentMethods[].paymentMethodId as beneficiaryPaymentMethodId when creating a payment.

Pagination is page-based, matching the rest of the Jeeves Public API. Pass page and limit; count in the response is the total matching the query across all pages, so stop once page × limit reaches it. The request page and limit are not echoed back — keep track of them yourself.

The envelope is data and count, and nothing else.

Deleted beneficiaries and deleted payment methods are never returned, and there is no status field on either.

Query
pageinteger>= 1

1-based page number. Defaults to 1.

Default 1
limitinteger[ 1 .. 200 ]

Rows per page. Defaults to 50. Values above 200 are clamped to 200 rather than rejected.

Default 50
searchstring<= 100 characters

Free-text filter. Matches name, firstName and lastName as a substring, and a payment method's account number by suffix.

curl -i -X GET \
  'https://public-sandbox.tryjeeves.com/v1/beneficiaries?limit=50&page=1&search=Acme' \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>'

Responses

A page of beneficiaries.

Headers
X-RateLimit-Limitinteger

Requests allowed in the current window.

Example: 300
X-RateLimit-Remaininginteger

Requests left in the current window.

Example: 297
X-RateLimit-Resetinteger

Unix time at which the window resets.

Example: 1789045760
Bodyapplication/json
dataArray of objects(Beneficiary)required
data[].​beneficiaryIdstring(uuid)required
data[].​entityTypestringrequired

Determines which name fields are populated: individual uses firstName and lastName; business uses name.

Enum"individual""business"
data[].​firstNamestring or null

Present for individuals.

data[].​lastNamestring or null

Present for individuals.

data[].​namestring or null

Registered business name. Present for businesses.

data[].​bankCountrystringrequired

ISO 3166-1 alpha-2.

data[].​bankCurrencystring or nullrequired

ISO 4217 alpha code, or one of the supported stablecoin tickers (USDB, USDC, USDT, EURC). null when the stored value is not a recognised currency code.

data[].​contactInformationobject(ContactInformation)

The beneficiary's contact details. Every key is always present and is null when the value is not set.

data[].​createdAtstring(date-time)required
data[].​paymentMethodsArray of objects(PaymentMethodSummary)required

Every live payment method attached to this beneficiary. May be empty.

data[].​paymentMethods[].​paymentMethodIdstring(uuid)required

Pass as beneficiaryPaymentMethodId when creating a payment.

data[].​paymentMethods[].​paymentMethodstringrequired

The rail, from a stable public set. A rail with no dedicated member is reported as local-clearing (a country-specific domestic system) or other. Treat as open.

data[].​paymentMethods[].​accountNumberstring or nullrequired

The destination account, masked: only the last four characters are shown. An account of four characters or fewer is masked completely, and a method with no account number is null.

countintegerrequired

Total beneficiaries matching the query, across all pages. Stop paging once page × limit reaches it. The request page and limit are not echoed back.

Response
application/json
{ "data": [ { … }, { … } ], "count": 42 }

Create a beneficiary

Request

Create a person or a business you pay. The beneficiary is created with no payment methods; read what the corridor needs with GET /v1/beneficiary-schemas, then attach a payment method with POST /v1/payment-methods.

Send firstName and lastName for an individual, or name for a business. Each name field is at most 255 characters. A required name field that is missing, or a name field that belongs to the other entityType, is a 422 (see below). Unknown fields are rejected with unknown_field, and a JSON array body is a 400.

bankCurrency must be one of the supported currencies listed on the field; any other value is a 400 with unsupported_value. A bankCountry that is well formed but not a known country is a 422 with unsupported_value.

Not idempotent. No Idempotency-Key is read; one that is sent is ignored. The duplicate check is your retry protection: a beneficiary with the same name, bank country and bank currency returns 422 with errors[].code: duplicate on the name field or fields (name for a business, firstName and lastName for an individual). That check also matches a Boleto-source vendor that GET /v1/beneficiaries does not list. Two simultaneous identical requests can both succeed, because nothing enforces uniqueness at the database.

Bodyapplication/jsonrequired
entityTypestringrequired

individual takes firstName and lastName; business takes name. A name field that belongs to the other type is rejected.

Enum"individual""business"
firstNamestring<= 255 characters

Required for an individual.

lastNamestring<= 255 characters

Required for an individual.

namestring<= 255 characters

Registered business name. Required for a business.

bankCountrystring^[A-Z]{2}$required

ISO 3166-1 alpha-2, uppercase.

bankCurrencystringrequired

ISO 4217 alpha code, or a supported stablecoin ticker.

Enum"USD""MXN""BRL""COP""EUR""GBP""CAD""USDB""USDC""USDT"
curl -i -X POST \
  https://public-sandbox.tryjeeves.com/v1/beneficiaries \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "entityType": "individual",
    "firstName": "Ana",
    "lastName": "Gómez",
    "bankCountry": "MX",
    "bankCurrency": "MXN"
  }'

Responses

Beneficiary created. It has no payment methods yet.

Bodyapplication/json
beneficiaryIdstring(uuid)required
statusstringrequired
Value"active"
createdAtstring(date-time)required
Response
application/json
{ "beneficiaryId": "3f1c9a52-6b7e-4d80-9a13-5c2e8f0b4d76", "status": "active", "createdAt": "2026-11-02T14:02:11Z" }

Get a beneficiary

Request

Fetch one beneficiary with its contactInformation and attached payment methods.

The response is the bare beneficiary object, identical to one entry of data[] in GET /v1/beneficiaries — there is no data or count envelope. Account numbers are masked to the last four characters; an account of four characters or fewer is masked completely, and a method with no account number is null.

An unknown, deleted or malformed beneficiaryId, or one that belongs to another customer, returns the same 404 beneficiary_not_found body. It is never a 403.

Path
beneficiaryIdstringrequired
Example: 3f1c9a52-6b7e-4d80-9a13-5c2e8f0b4d76
curl -i -X GET \
  https://public-sandbox.tryjeeves.com/v1/beneficiaries/3f1c9a52-6b7e-4d80-9a13-5c2e8f0b4d76 \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>'

Responses

The beneficiary.

Bodyapplication/json
beneficiaryIdstring(uuid)required
entityTypestringrequired

Determines which name fields are populated: individual uses firstName and lastName; business uses name.

Enum"individual""business"
firstNamestring or null

Present for individuals.

lastNamestring or null

Present for individuals.

namestring or null

Registered business name. Present for businesses.

bankCountrystringrequired

ISO 3166-1 alpha-2.

bankCurrencystring or nullrequired

ISO 4217 alpha code, or one of the supported stablecoin tickers (USDB, USDC, USDT, EURC). null when the stored value is not a recognised currency code.

contactInformationobject(ContactInformation)

The beneficiary's contact details. Every key is always present and is null when the value is not set.

createdAtstring(date-time)required
paymentMethodsArray of objects(PaymentMethodSummary)required

Every live payment method attached to this beneficiary. May be empty.

paymentMethods[].​paymentMethodIdstring(uuid)required

Pass as beneficiaryPaymentMethodId when creating a payment.

paymentMethods[].​paymentMethodstringrequired

The rail, from a stable public set. A rail with no dedicated member is reported as local-clearing (a country-specific domestic system) or other. Treat as open.

paymentMethods[].​accountNumberstring or nullrequired

The destination account, masked: only the last four characters are shown. An account of four characters or fewer is masked completely, and a method with no account number is null.

Response
application/json
{ "beneficiaryId": "3f1c9a52-6b7e-4d80-9a13-5c2e8f0b4d76", "entityType": "individual", "firstName": "Ana", "lastName": "Gómez", "name": null, "bankCountry": "MX", "bankCurrency": "MXN", "contactInformation": { "streetAddress": null, "city": null, "state": null, "postcode": null, "countryCode": null, "phoneNumber": null, "emailAddress": null }, "createdAt": "2026-09-10T14:02:11Z", "paymentMethods": [ { … } ] }

Get what a corridor needs

Request

Ask what a corridor needs before you attach a payment method or create a payment. For each payment method on offer the response lists the bankingInformation fields, the contactInformation fields and the purpose codes.

  • fields[].fieldName values are the keys of bankingInformation on POST /v1/payment-methods.
  • contactFields[].fieldName values are the keys of contactInformation. The list is empty when the method needs none.
  • purposeCodes[] is the exact list that payment-time validation accepts.

Patterns and purposeCode are enforced again when you create the payment.

entityType is required because the form depends on it. Your company must hold the funding source you name with sourceCurrency and productAccountType; the methods and purpose codes returned are those for that funding source. Pass paymentMethod to narrow the response to one method.

Use the paymentMethod value from this response, unchanged, when you call POST /v1/payment-methods. Reading a beneficiary (GET /v1/beneficiaries) reports the payment method in a normalised vocabulary instead (ach, spei, wire and so on), so the two lists are not interchangeable.

Query
sourceCurrencystringrequired

The currency you pay from, as in POST /v1/quotes.

Enum"USD""MXN""BRL""COP""EUR""GBP""CAD""USDB""USDC""USDT"
Example: sourceCurrency=USD
productAccountTypestringrequired

The kind of account you pay from.

Enum"credit-line""self-funded""crypto-wallet"
Example: productAccountType=self-funded
destinationCountrystring^[A-Z]{2}$required

ISO 3166-1 alpha-2, uppercase.

Example: destinationCountry=MX
destinationCurrencystringrequired

The currency the beneficiary receives.

Enum"USD""MXN""BRL""COP""EUR""GBP""CAD""USDB""USDC""USDT"
Example: destinationCurrency=MXN
entityTypestringrequired

Whether the beneficiary is a person or a business.

Enum"individual""business"
Example: entityType=individual
paymentMethodstring

Narrow the response to one payment method, using a paymentMethod value as this endpoint returns it.

Example: paymentMethod=local_bank_transfer
curl -i -X GET \
  'https://public-sandbox.tryjeeves.com/v1/beneficiary-schemas?destinationCountry=MX&destinationCurrency=MXN&entityType=individual&paymentMethod=local_bank_transfer&productAccountType=self-funded&sourceCurrency=USD' \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>'

Responses

The payment methods on offer for the corridor.

Bodyapplication/json
paymentMethodsArray of objects(BeneficiarySchemaPaymentMethod)required
paymentMethods[].​paymentMethodstringrequired

Send exactly this value as paymentMethod on POST /v1/payment-methods. It is not the normalised vocabulary used when you read a beneficiary.

paymentMethods[].​fieldsArray of objects(SchemaField)required

The keys of bankingInformation.

paymentMethods[].​fields[].​fieldNamestringrequired

The key to send in the request object this field belongs to.

paymentMethods[].​fields[].​typestringrequired
Enum"string""enum""number"
paymentMethods[].​fields[].​requiredbooleanrequired
paymentMethods[].​fields[].​patternstring

Regular expression the value must match. Present when the field has one.

paymentMethods[].​fields[].​allowedValuesArray of strings or numbers

The values the field accepts. Present when type is enum.

paymentMethods[].​fields[].​descriptionstringrequired
paymentMethods[].​contactFieldsArray of objects(SchemaField)required

The keys of contactInformation. Empty when the method needs none.

paymentMethods[].​contactFields[].​fieldNamestringrequired

The key to send in the request object this field belongs to.

paymentMethods[].​contactFields[].​typestringrequired
Enum"string""enum""number"
paymentMethods[].​contactFields[].​requiredbooleanrequired
paymentMethods[].​contactFields[].​patternstring

Regular expression the value must match. Present when the field has one.

paymentMethods[].​contactFields[].​allowedValuesArray of strings or numbers

The values the field accepts. Present when type is enum.

paymentMethods[].​contactFields[].​descriptionstringrequired
paymentMethods[].​purposeCodesArray of objects(PurposeCodeOption)required

The exact list of purpose codes that payment-time validation accepts.

paymentMethods[].​purposeCodes[].​codestringrequired

Send as purposeCode when creating a payment.

paymentMethods[].​purposeCodes[].​descriptionstringrequired
Response
application/json
{ "paymentMethods": [ { … } ] }

Attach a payment method

Request

Attach a payment method to a beneficiary. Use the returned paymentMethodId as beneficiaryPaymentMethodId when you create a payment.

The corridor comes from the beneficiary's stored bank country and currency, so there are no corridor parameters. paymentMethod must be a value returned by GET /v1/beneficiary-schemas; the keys of bankingInformation must equal that response's fields[].fieldName, and each value is checked against its pattern.

contactInformation is required when the method's contactFields is not empty, unless the beneficiary already has the value stored. When contactFields is empty, any contact key is rejected with unknown_field.

One payment method per rail per beneficiary. The duplicate check looks at paymentMethod only, not at the account number. To replace a method you would have to delete the old one first, and the public API has no delete.

Send paymentMethod exactly as GET /v1/beneficiary-schemas returns it. The payment method on a beneficiary you read back is reported in a normalised vocabulary, so it may not equal the value you sent.

Not idempotent. No Idempotency-Key is read, and a retry after a success returns 409 payment_method_already_exists.

Bodyapplication/jsonrequired
beneficiaryIdstring(uuid)required
paymentMethodstringrequired

A paymentMethod value, unchanged, from GET /v1/beneficiary-schemas.

bankingInformationobjectrequired

Keys equal the fields[].fieldName values from GET /v1/beneficiary-schemas; each value is checked against that field's pattern.

bankingInformation.​property name*string or numberadditional property
One of:
string
contactInformationobject

The beneficiary's contact details. Every key is always present and is null when the value is not set.

curl -i -X POST \
  https://public-sandbox.tryjeeves.com/v1/payment-methods \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "beneficiaryId": "3f1c9a52-6b7e-4d80-9a13-5c2e8f0b4d76",
    "paymentMethod": "local_bank_transfer",
    "bankingInformation": {
      "accountNumber": "0123456789",
      "bankCode": "021000021"
    }
  }'

Responses

Payment method attached.

Bodyapplication/json
paymentMethodIdstring(uuid)required

Send as beneficiaryPaymentMethodId when creating a payment.

statusstringrequired
Value"active"
Response
application/json
{ "paymentMethodId": "b7d2e4a1-8c05-49f3-a6b2-1e7d9c3f5024", "status": "active" }

Quotes

Lock an FX rate before creating a payment.

Operations

Payments

Create a payment against a quote and track it to a terminal status.

OperationsWebhooks