Skip to content

Cancel a payment

POST
/api/v1/payments/{payment_id}/cancel
curl --request POST \
--url https://api.elephants.inc/api/v1/payments/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/cancel \
--header 'Authorization: Bearer <token>'

Requests cancellation of a crypto payment parked at the custody partner for spending-policy approval.

Accepted only while the payment reports cancellable: true; other states answer 409 not_cancellable. On success the payment’s status becomes cancelling and its deducted amount stays reserved until the partner confirms the rejection, after which the status becomes cancelled and the balance is restored. If the partner approves the transfer first, the payment proceeds and reports succeeded.

payment_id
required
string format: uuid

Payment ID

The payment, now cancelling

Media typeapplication/json
Payment
object
approval_request_id
required
string | null format: uuid
cancellable
required

Whether cancelPayment will be accepted right now. True only while a crypto withdrawal waits for the custody partner’s approval; earlier states resolve on their own and later ones are on-chain.

boolean
created_at
required
string format: date-time
deducting
required

Coupled amount+currency deducted from the sender

object
amount
required

Decimal string at the currency’s precision, e.g. “10.50”

string
<= 255 characters
currency
required

Three-letter currency code, e.g. “USD”

string
<= 16 characters
destination_id
required
string format: uuid
destination_name
required
string
event
required
One of:
OperationEvent
object
id
required

The domain event’s id

string format: uuid
stream
required

The event stream it was written to, e.g. “payment_contact_events”

string
subject_id
required

The id of the aggregate the event belongs to

string format: uuid
type
required

The event type, e.g. “payment_contact.created”

string
id
required
string format: uuid
internal_notes
required
string | null
landing
required

Coupled amount+currency delivered to the recipient

object
amount
required

Decimal string at the currency’s precision, e.g. “10.50”

string
<= 255 characters
currency
required

Three-letter currency code, e.g. “USD”

string
<= 16 characters
organization_id
required
string format: uuid
payment_batch_id
required

The payment batch this payment is one row of; pass to getPaymentBatch. Null for a payment sent on its own. A batch row has no approval request of its own: the batch’s request covers it.

string | null format: uuid
payment_contact_id
required
string format: uuid
quote_id
required

The quote the payment was executed from. Null for a payment to an Ele ID, which is created without a quote.

string | null format: uuid
rail
required
string
Allowed values: fiat crypto ele_id
status
required
string
Allowed values: awaiting_approval submitted processing on_hold cancelling succeeded failed reversed cancelled
status_detail
required

Non-contractual raw rail state for diagnostics

string
tag
required
string | null
Allowed values: vendor own_account employee other
transaction_id
required

Id of this payment’s row in the transactions feed — pass to getTransaction. Null when the payment has no feed row: legacy payments that predate the feed, or payments whose feed entries have been discarded or archived.

string | null format: uuid

Example

{
"rail": "fiat",
"status": "awaiting_approval",
"tag": "vendor"
}

Invalid request parameters or body

Media typeapplication/json
Error

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

object
error
required
object
details

Structured error details (e.g. validation errors), when present

message
required

Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.

string
request_id

Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.

string
step_up
Any of:
StepUpChallenge
object
delivery
required

Method used to deliver this challenge

string
expires_at
required

Challenge expiry

string | null format: date-time
id
required

Sudo session ID returned to completeStepUp

string
match_code
required

3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.

string | null
methods
required

Available verification methods

Array<string>
step_up_authentication_id
required

The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.

string format: uuid
webauthn
required
Any of:
PasskeyAuthenticationOptions
object
allow_credentials
required
Array<object>
object
id
required
string
transports
required
Array<string>
type
required
string
challenge
required
string
challenge_id
required
string format: uuid
rp_id
required
string
timeout
required
integer
user_verification
required
string
type
required

Machine-readable error code from a stable vocabulary (open enum — handle unknown values)

string

Example generated

{
"error": {
"details": "example",
"message": "example",
"request_id": "example",
"step_up": {
"delivery": "example",
"expires_at": "2026-04-15T12:00:00Z",
"id": "example",
"match_code": "example",
"methods": [
"example"
],
"step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"webauthn": {
"allow_credentials": [
{
"id": "example",
"transports": [
"example"
],
"type": "example"
}
],
"challenge": "example",
"challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"rp_id": "example",
"timeout": 1,
"user_verification": "example"
}
},
"type": "example"
}
}

Missing, invalid, or expired bearer token

Media typeapplication/json
Error

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

object
error
required
object
details

Structured error details (e.g. validation errors), when present

message
required

Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.

string
request_id

Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.

string
step_up
Any of:
StepUpChallenge
object
delivery
required

Method used to deliver this challenge

string
expires_at
required

Challenge expiry

string | null format: date-time
id
required

Sudo session ID returned to completeStepUp

string
match_code
required

3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.

string | null
methods
required

Available verification methods

Array<string>
step_up_authentication_id
required

The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.

string format: uuid
webauthn
required
Any of:
PasskeyAuthenticationOptions
object
allow_credentials
required
Array<object>
object
id
required
string
transports
required
Array<string>
type
required
string
challenge
required
string
challenge_id
required
string format: uuid
rp_id
required
string
timeout
required
integer
user_verification
required
string
type
required

Machine-readable error code from a stable vocabulary (open enum — handle unknown values)

string

Example generated

{
"error": {
"details": "example",
"message": "example",
"request_id": "example",
"step_up": {
"delivery": "example",
"expires_at": "2026-04-15T12:00:00Z",
"id": "example",
"match_code": "example",
"methods": [
"example"
],
"step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"webauthn": {
"allow_credentials": [
{
"id": "example",
"transports": [
"example"
],
"type": "example"
}
],
"challenge": "example",
"challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"rp_id": "example",
"timeout": 1,
"user_verification": "example"
}
},
"type": "example"
}
}

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

Media typeapplication/json
Error

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

object
error
required
object
details

Structured error details (e.g. validation errors), when present

message
required

Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.

string
request_id

Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.

string
step_up
Any of:
StepUpChallenge
object
delivery
required

Method used to deliver this challenge

string
expires_at
required

Challenge expiry

string | null format: date-time
id
required

Sudo session ID returned to completeStepUp

string
match_code
required

3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.

string | null
methods
required

Available verification methods

Array<string>
step_up_authentication_id
required

The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.

string format: uuid
webauthn
required
Any of:
PasskeyAuthenticationOptions
object
allow_credentials
required
Array<object>
object
id
required
string
transports
required
Array<string>
type
required
string
challenge
required
string
challenge_id
required
string format: uuid
rp_id
required
string
timeout
required
integer
user_verification
required
string
type
required

Machine-readable error code from a stable vocabulary (open enum — handle unknown values)

string

Example generated

{
"error": {
"details": "example",
"message": "example",
"request_id": "example",
"step_up": {
"delivery": "example",
"expires_at": "2026-04-15T12:00:00Z",
"id": "example",
"match_code": "example",
"methods": [
"example"
],
"step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"webauthn": {
"allow_credentials": [
{
"id": "example",
"transports": [
"example"
],
"type": "example"
}
],
"challenge": "example",
"challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"rp_id": "example",
"timeout": 1,
"user_verification": "example"
}
},
"type": "example"
}
}

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

Media typeapplication/json
Error

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

object
error
required
object
details

Structured error details (e.g. validation errors), when present

message
required

Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.

string
request_id

Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.

string
step_up
Any of:
StepUpChallenge
object
delivery
required

Method used to deliver this challenge

string
expires_at
required

Challenge expiry

string | null format: date-time
id
required

Sudo session ID returned to completeStepUp

string
match_code
required

3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.

string | null
methods
required

Available verification methods

Array<string>
step_up_authentication_id
required

The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.

string format: uuid
webauthn
required
Any of:
PasskeyAuthenticationOptions
object
allow_credentials
required
Array<object>
object
id
required
string
transports
required
Array<string>
type
required
string
challenge
required
string
challenge_id
required
string format: uuid
rp_id
required
string
timeout
required
integer
user_verification
required
string
type
required

Machine-readable error code from a stable vocabulary (open enum — handle unknown values)

string

Example generated

{
"error": {
"details": "example",
"message": "example",
"request_id": "example",
"step_up": {
"delivery": "example",
"expires_at": "2026-04-15T12:00:00Z",
"id": "example",
"match_code": "example",
"methods": [
"example"
],
"step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"webauthn": {
"allow_credentials": [
{
"id": "example",
"transports": [
"example"
],
"type": "example"
}
],
"challenge": "example",
"challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"rp_id": "example",
"timeout": 1,
"user_verification": "example"
}
},
"type": "example"
}
}

Not_cancellable: the payment is not in a cancellable state

Media typeapplication/json
Error

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

object
error
required
object
details

Structured error details (e.g. validation errors), when present

message
required

Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.

string
request_id

Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.

string
step_up
Any of:
StepUpChallenge
object
delivery
required

Method used to deliver this challenge

string
expires_at
required

Challenge expiry

string | null format: date-time
id
required

Sudo session ID returned to completeStepUp

string
match_code
required

3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.

string | null
methods
required

Available verification methods

Array<string>
step_up_authentication_id
required

The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.

string format: uuid
webauthn
required
Any of:
PasskeyAuthenticationOptions
object
allow_credentials
required
Array<object>
object
id
required
string
transports
required
Array<string>
type
required
string
challenge
required
string
challenge_id
required
string format: uuid
rp_id
required
string
timeout
required
integer
user_verification
required
string
type
required

Machine-readable error code from a stable vocabulary (open enum — handle unknown values)

string

Example generated

{
"error": {
"details": "example",
"message": "example",
"request_id": "example",
"step_up": {
"delivery": "example",
"expires_at": "2026-04-15T12:00:00Z",
"id": "example",
"match_code": "example",
"methods": [
"example"
],
"step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"webauthn": {
"allow_credentials": [
{
"id": "example",
"transports": [
"example"
],
"type": "example"
}
],
"challenge": "example",
"challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"rp_id": "example",
"timeout": 1,
"user_verification": "example"
}
},
"type": "example"
}
}

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

Media typeapplication/json
Error

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

object
error
required
object
details

Structured error details (e.g. validation errors), when present

message
required

Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.

string
request_id

Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.

string
step_up
Any of:
StepUpChallenge
object
delivery
required

Method used to deliver this challenge

string
expires_at
required

Challenge expiry

string | null format: date-time
id
required

Sudo session ID returned to completeStepUp

string
match_code
required

3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.

string | null
methods
required

Available verification methods

Array<string>
step_up_authentication_id
required

The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.

string format: uuid
webauthn
required
Any of:
PasskeyAuthenticationOptions
object
allow_credentials
required
Array<object>
object
id
required
string
transports
required
Array<string>
type
required
string
challenge
required
string
challenge_id
required
string format: uuid
rp_id
required
string
timeout
required
integer
user_verification
required
string
type
required

Machine-readable error code from a stable vocabulary (open enum — handle unknown values)

string

Example generated

{
"error": {
"details": "example",
"message": "example",
"request_id": "example",
"step_up": {
"delivery": "example",
"expires_at": "2026-04-15T12:00:00Z",
"id": "example",
"match_code": "example",
"methods": [
"example"
],
"step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"webauthn": {
"allow_credentials": [
{
"id": "example",
"transports": [
"example"
],
"type": "example"
}
],
"challenge": "example",
"challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"rp_id": "example",
"timeout": 1,
"user_verification": "example"
}
},
"type": "example"
}
}

Too many requests

Media typeapplication/json
RateLimitedError
object
error
required
object
details

Structured error details (e.g. validation errors), when present

message
required

Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.

string
request_id

Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.

string
step_up
Any of:
StepUpChallenge
object
delivery
required

Method used to deliver this challenge

string
expires_at
required

Challenge expiry

string | null format: date-time
id
required

Sudo session ID returned to completeStepUp

string
match_code
required

3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.

string | null
methods
required

Available verification methods

Array<string>
step_up_authentication_id
required

The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.

string format: uuid
webauthn
required
Any of:
PasskeyAuthenticationOptions
object
allow_credentials
required
Array<object>
object
id
required
string
transports
required
Array<string>
type
required
string
challenge
required
string
challenge_id
required
string format: uuid
rp_id
required
string
timeout
required
integer
user_verification
required
string
type
required

Machine-readable error code from a stable vocabulary (open enum — handle unknown values)

string
error
required
object
type
required
string
Allowed value: rate_limited

Example

{
"error": {
"type": "rate_limited"
}
}
Retry-After
required
string

How long to wait before retrying, expressed as delay seconds or an HTTP date

Unexpected server error

Media typeapplication/json
Error

Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.

object
error
required
object
details

Structured error details (e.g. validation errors), when present

message
required

Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.

string
request_id

Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.

string
step_up
Any of:
StepUpChallenge
object
delivery
required

Method used to deliver this challenge

string
expires_at
required

Challenge expiry

string | null format: date-time
id
required

Sudo session ID returned to completeStepUp

string
match_code
required

3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.

string | null
methods
required

Available verification methods

Array<string>
step_up_authentication_id
required

The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.

string format: uuid
webauthn
required
Any of:
PasskeyAuthenticationOptions
object
allow_credentials
required
Array<object>
object
id
required
string
transports
required
Array<string>
type
required
string
challenge
required
string
challenge_id
required
string format: uuid
rp_id
required
string
timeout
required
integer
user_verification
required
string
type
required

Machine-readable error code from a stable vocabulary (open enum — handle unknown values)

string

Example generated

{
"error": {
"details": "example",
"message": "example",
"request_id": "example",
"step_up": {
"delivery": "example",
"expires_at": "2026-04-15T12:00:00Z",
"id": "example",
"match_code": "example",
"methods": [
"example"
],
"step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"webauthn": {
"allow_credentials": [
{
"id": "example",
"transports": [
"example"
],
"type": "example"
}
],
"challenge": "example",
"challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"rp_id": "example",
"timeout": 1,
"user_verification": "example"
}
},
"type": "example"
}
}