Skip to content
Get started

Paykeys

Paykeys are secure tokens that link verified customer identities to their bank accounts. Each Paykey includes built-in balance checking, fraud detection through LSTM machine learning models, and can be reused for subscriptions and recurring payments without storing sensitive data. Paykeys eliminate fraud by ensuring the person initiating payment owns the funding account.

Lookup a paykey
GET/v1/paykeys/{id}
Unmask a paykey
GET/v1/paykeys/{id}/unmasked
List paykeys
GET/v1/paykeys
Retrieve an unmasked paykey token
GET/v1/paykeys/{id}/reveal
Cancel
PUT/v1/paykeys/{id}/cancel
Update a paykey's balance
PUT/v1/paykeys/{id}/refresh_balance
ModelsExpand Collapse
PaykeySummaryPagedV1 = object { data, meta, response_type }
data: array of object { id, config, created_at, 12 more }
id: string

Unique identifier for the paykey.

formatuuid
config: object { processing_method, sandbox_outcome }
processing_method: optional "inline" or "background" or "skip"
One of the following:
"inline"
"background"
"skip"
sandbox_outcome: optional "standard" or "active" or "rejected" or "review"
One of the following:
"standard"
"active"
"rejected"
"review"
created_at: string

Timestamp of when the paykey was created.

formatdate-time
label: string

Human-readable label that combines the bank name and masked account number to help easility represent this paykey in a UI

paykey: string

The tokenized paykey value. This value is used to create payments and should be stored securely.

source: "bank_account" or "straddle" or "mx" or 3 more
One of the following:
"bank_account"
"straddle"
"mx"
"plaid"
"tan"
"quiltt"
status: "pending" or "active" or "inactive" or 3 more
One of the following:
"pending"
"active"
"inactive"
"rejected"
"review"
"blocked"
updated_at: string

Timestamp of the most recent update to the paykey.

formatdate-time
bank_data: optional object { account_number, account_type, routing_number }
account_number: string

Bank account number. This value is masked by default for security reasons. Use the /unmask endpoint to access the unmasked value.

account_type: "checking" or "savings"
One of the following:
"checking"
"savings"
routing_number: string

The routing number of the bank account.

minLength9
maxLength9
customer_id: optional string

Unique identifier of the related customer object.

formatuuid
expires_at: optional string

Expiration date and time of the paykey, if applicable.

formatdate-time
external_id: optional string

Unique identifier for the paykey in your database, used for cross-referencing between Straddle and your systems.

institution_name: optional string

Name of the financial institution.

status_details: optional object { changed_at, message, reason, 2 more }
changed_at: string

The time the status change occurred.

formatdate-time
message: string

A human-readable description of the current status.

reason: "insufficient_funds" or "closed_bank_account" or "invalid_bank_account" or 24 more
One of the following:
"insufficient_funds"
"closed_bank_account"
"invalid_bank_account"
"invalid_routing"
"disputed"
"payment_stopped"
"owner_deceased"
"frozen_bank_account"
"risk_review"
"fraudulent"
"duplicate_entry"
"invalid_paykey"
"payment_blocked"
"amount_too_large"
"too_many_attempts"
"internal_system_error"
"user_request"
"ok"
"other_network_return"
"payout_refused"
"cancel_request"
"failed_verification"
"require_review"
"blocked_by_system"
"watchtower_review"
"validating"
"auto_hold"
source: "watchtower" or "bank_decline" or "customer_dispute" or 2 more
One of the following:
"watchtower"
"bank_decline"
"customer_dispute"
"user_action"
"system"
code: optional string

The status code if applicable.

unblock_eligible: optional boolean

Indicates whether this paykey is eligible for client-initiated unblocking. Only present for blocked paykeys. True when blocked due to R29 returns and not previously unblocked, false otherwise. Null when paykey is not blocked.

meta: object { api_request_id, api_request_timestamp, max_page_size, 6 more }
api_request_id: string

Unique identifier for this API request, useful for troubleshooting.

formatuuid
api_request_timestamp: string

Timestamp for this API request, useful for troubleshooting.

formatdate-time
max_page_size: number

Maximum allowed page size for this endpoint.

formatint32
page_number: number

Page number for paginated results.

formatint32
page_size: number

Number of items per page in this response.

formatint32
sort_by: string

The field that the results were sorted by.

sort_order: "asc" or "desc"
One of the following:
"asc"
"desc"
total_items: number
total_pages: number

The number of pages available.

formatint32
response_type: "object" or "array" or "error" or "none"

Indicates the structure of the returned content.

  • "object" means the data field contains a single JSON object.
  • "array" means the data field contains an array of objects.
  • "error" means the data field contains an error object with details of the issue.
  • "none" means no data is returned.
One of the following:
"object"
"array"
"error"
"none"
PaykeyUnmaskedV1 = object { data, meta, response_type }
data: object { id, config, created_at, 13 more }
id: string

Unique identifier for the paykey.

formatuuid
config: object { processing_method, sandbox_outcome }
processing_method: optional "inline" or "background" or "skip"
One of the following:
"inline"
"background"
"skip"
sandbox_outcome: optional "standard" or "active" or "rejected" or "review"
One of the following:
"standard"
"active"
"rejected"
"review"
created_at: string

Timestamp of when the paykey was created.

formatdate-time
label: string

Human-readable label used to represent this paykey in a UI.

paykey: string

The tokenized paykey value. This value is used to create payments and should be stored securely.

source: "bank_account" or "straddle" or "mx" or 3 more
One of the following:
"bank_account"
"straddle"
"mx"
"plaid"
"tan"
"quiltt"
status: "pending" or "active" or "inactive" or 3 more
One of the following:
"pending"
"active"
"inactive"
"rejected"
"review"
"blocked"
updated_at: string

Timestamp of the most recent update to the paykey.

formatdate-time
balance: optional object { status, account_balance, updated_at }
status: "pending" or "completed" or "failed"
One of the following:
"pending"
"completed"
"failed"
account_balance: optional number

Account Balance when last retrieved

formatint32
updated_at: optional string

Last time account balance was updated.

formatdate-time
bank_data: optional object { account_number, account_type, routing_number }
account_number: string

The bank account number

account_type: "checking" or "savings"
One of the following:
"checking"
"savings"
routing_number: string

The routing number of the bank account.

minLength9
maxLength9
customer_id: optional string

Unique identifier of the related customer object.

formatuuid
expires_at: optional string

Expiration date and time of the paykey, if applicable.

formatdate-time
external_id: optional string

Unique identifier for the paykey in your database, used for cross-referencing between Straddle and your systems.

institution_name: optional string

Name of the financial institution.

metadata: optional map[string]

Up to 20 additional user-defined key-value pairs. Useful for storing additional information about the paykey in a structured format.

status_details: optional object { changed_at, message, reason, 2 more }
changed_at: string

The time the status change occurred.

formatdate-time
message: string

A human-readable description of the current status.

reason: "insufficient_funds" or "closed_bank_account" or "invalid_bank_account" or 24 more
One of the following:
"insufficient_funds"
"closed_bank_account"
"invalid_bank_account"
"invalid_routing"
"disputed"
"payment_stopped"
"owner_deceased"
"frozen_bank_account"
"risk_review"
"fraudulent"
"duplicate_entry"
"invalid_paykey"
"payment_blocked"
"amount_too_large"
"too_many_attempts"
"internal_system_error"
"user_request"
"ok"
"other_network_return"
"payout_refused"
"cancel_request"
"failed_verification"
"require_review"
"blocked_by_system"
"watchtower_review"
"validating"
"auto_hold"
source: "watchtower" or "bank_decline" or "customer_dispute" or 2 more
One of the following:
"watchtower"
"bank_decline"
"customer_dispute"
"user_action"
"system"
code: optional string

The status code if applicable.

meta: ResponseMetadata { api_request_id, api_request_timestamp }

Metadata about the API request, including an identifier and timestamp.

api_request_id: string

Unique identifier for this API request, useful for troubleshooting.

formatuuid
api_request_timestamp: string

Timestamp for this API request, useful for troubleshooting.

formatdate-time
response_type: "object" or "array" or "error" or "none"

Indicates the structure of the returned content.

  • "object" means the data field contains a single JSON object.
  • "array" means the data field contains an array of objects.
  • "error" means the data field contains an error object with details of the issue.
  • "none" means no data is returned.
One of the following:
"object"
"array"
"error"
"none"
PaykeyV1 = object { data, meta, response_type }
data: object { id, config, created_at, 14 more }
id: string

Unique identifier for the paykey.

formatuuid
config: object { processing_method, sandbox_outcome }
processing_method: optional "inline" or "background" or "skip"
One of the following:
"inline"
"background"
"skip"
sandbox_outcome: optional "standard" or "active" or "rejected" or "review"
One of the following:
"standard"
"active"
"rejected"
"review"
created_at: string

Timestamp of when the paykey was created.

formatdate-time
label: string

Human-readable label used to represent this paykey in a UI.

paykey: string

The tokenized paykey value. This value is used to create payments and should be stored securely.

source: "bank_account" or "straddle" or "mx" or 3 more
One of the following:
"bank_account"
"straddle"
"mx"
"plaid"
"tan"
"quiltt"
status: "pending" or "active" or "inactive" or 3 more
One of the following:
"pending"
"active"
"inactive"
"rejected"
"review"
"blocked"
updated_at: string

Timestamp of the most recent update to the paykey.

formatdate-time
balance: optional object { status, account_balance, updated_at }
status: "pending" or "completed" or "failed"
One of the following:
"pending"
"completed"
"failed"
account_balance: optional number

Account Balance when last retrieved

formatint32
updated_at: optional string

Last time account balance was updated.

formatdate-time
bank_data: optional object { account_number, account_type, routing_number }
account_number: string

Bank account number. This value is masked by default for security reasons. Use the /unmask endpoint to access the unmasked value.

account_type: "checking" or "savings"
One of the following:
"checking"
"savings"
routing_number: string

The routing number of the bank account.

minLength9
maxLength9
customer_id: optional string

Unique identifier of the related customer object.

formatuuid
expires_at: optional string

Expiration date and time of the paykey, if applicable.

formatdate-time
external_id: optional string

Unique identifier for the paykey in your database, used for cross-referencing between Straddle and your systems.

institution_name: optional string

Name of the financial institution.

metadata: optional map[string]

Up to 20 additional user-defined key-value pairs. Useful for storing additional information about the paykey in a structured format.

status_details: optional object { changed_at, message, reason, 2 more }
changed_at: string

The time the status change occurred.

formatdate-time
message: string

A human-readable description of the current status.

reason: "insufficient_funds" or "closed_bank_account" or "invalid_bank_account" or 24 more
One of the following:
"insufficient_funds"
"closed_bank_account"
"invalid_bank_account"
"invalid_routing"
"disputed"
"payment_stopped"
"owner_deceased"
"frozen_bank_account"
"risk_review"
"fraudulent"
"duplicate_entry"
"invalid_paykey"
"payment_blocked"
"amount_too_large"
"too_many_attempts"
"internal_system_error"
"user_request"
"ok"
"other_network_return"
"payout_refused"
"cancel_request"
"failed_verification"
"require_review"
"blocked_by_system"
"watchtower_review"
"validating"
"auto_hold"
source: "watchtower" or "bank_decline" or "customer_dispute" or 2 more
One of the following:
"watchtower"
"bank_decline"
"customer_dispute"
"user_action"
"system"
code: optional string

The status code if applicable.

unblock_eligible: optional boolean

Indicates whether this paykey is eligible for client-initiated unblocking. Only present for blocked paykeys. True when blocked due to R29 returns and not previously unblocked, false otherwise. Null when paykey is not blocked.

meta: ResponseMetadata { api_request_id, api_request_timestamp }

Metadata about the API request, including an identifier and timestamp.

api_request_id: string

Unique identifier for this API request, useful for troubleshooting.

formatuuid
api_request_timestamp: string

Timestamp for this API request, useful for troubleshooting.

formatdate-time
response_type: "object" or "array" or "error" or "none"

Indicates the structure of the returned content.

  • "object" means the data field contains a single JSON object.
  • "array" means the data field contains an array of objects.
  • "error" means the data field contains an error object with details of the issue.
  • "none" means no data is returned.
One of the following:
"object"
"array"
"error"
"none"
PaykeyRevealResponse = object { data, meta, response_type }
data: object { id, config, created_at, 13 more }
id: string

Unique identifier for the paykey.

formatuuid
config: object { processing_method, sandbox_outcome }
processing_method: optional "inline" or "background" or "skip"
One of the following:
"inline"
"background"
"skip"
sandbox_outcome: optional "standard" or "active" or "rejected" or "review"
One of the following:
"standard"
"active"
"rejected"
"review"
created_at: string

Timestamp of when the paykey was created.

formatdate-time
label: string

Human-readable label that combines the bank name and masked account number to help easility represent this paykey in a UI

paykey: string

The tokenized paykey value. This token is used to create payments and should be stored securely.

source: "bank_account" or "straddle" or "mx" or 3 more
One of the following:
"bank_account"
"straddle"
"mx"
"plaid"
"tan"
"quiltt"
status: "pending" or "active" or "inactive" or 3 more
One of the following:
"pending"
"active"
"inactive"
"rejected"
"review"
"blocked"
updated_at: string

Timestamp of the most recent update to the paykey.

formatdate-time
balance: optional object { status, account_balance, updated_at }
status: "pending" or "completed" or "failed"
One of the following:
"pending"
"completed"
"failed"
account_balance: optional number

Account Balance when last retrieved

formatint32
updated_at: optional string

Last time account balance was updated.

formatdate-time
bank_data: optional object { account_number, account_type, routing_number }
account_number: string

Bank account number. This value is masked by default for security reasons. Use the /unmask endpoint to access the unmasked value.

account_type: "checking" or "savings"
One of the following:
"checking"
"savings"
routing_number: string

The routing number of the bank account.

minLength9
maxLength9
customer_id: optional string

Unique identifier of the related customer object.

formatuuid
expires_at: optional string

Expiration date and time of the paykey, if applicable.

formatdate-time
external_id: optional string

Unique identifier for the paykey in your database, used for cross-referencing between Straddle and your systems.

institution_name: optional string

Name of the financial institution.

metadata: optional map[string]

Up to 20 additional user-defined key-value pairs. Useful for storing additional information about the paykey in a structured format.

status_details: optional object { changed_at, message, reason, 2 more }
changed_at: string

The time the status change occurred.

formatdate-time
message: string

A human-readable description of the current status.

reason: "insufficient_funds" or "closed_bank_account" or "invalid_bank_account" or 24 more
One of the following:
"insufficient_funds"
"closed_bank_account"
"invalid_bank_account"
"invalid_routing"
"disputed"
"payment_stopped"
"owner_deceased"
"frozen_bank_account"
"risk_review"
"fraudulent"
"duplicate_entry"
"invalid_paykey"
"payment_blocked"
"amount_too_large"
"too_many_attempts"
"internal_system_error"
"user_request"
"ok"
"other_network_return"
"payout_refused"
"cancel_request"
"failed_verification"
"require_review"
"blocked_by_system"
"watchtower_review"
"validating"
"auto_hold"
source: "watchtower" or "bank_decline" or "customer_dispute" or 2 more
One of the following:
"watchtower"
"bank_decline"
"customer_dispute"
"user_action"
"system"
code: optional string

The status code if applicable.

meta: ResponseMetadata { api_request_id, api_request_timestamp }

Metadata about the API request, including an identifier and timestamp.

api_request_id: string

Unique identifier for this API request, useful for troubleshooting.

formatuuid
api_request_timestamp: string

Timestamp for this API request, useful for troubleshooting.

formatdate-time
response_type: "object" or "array" or "error" or "none"

Indicates the structure of the returned content.

  • "object" means the data field contains a single JSON object.
  • "array" means the data field contains an array of objects.
  • "error" means the data field contains an error object with details of the issue.
  • "none" means no data is returned.
One of the following:
"object"
"array"
"error"
"none"

PaykeysReview

Paykeys are secure tokens that link verified customer identities to their bank accounts. Each Paykey includes built-in balance checking, fraud detection through LSTM machine learning models, and can be reused for subscriptions and recurring payments without storing sensitive data. Paykeys eliminate fraud by ensuring the person initiating payment owns the funding account.

Update a paykey's status
PATCH/v1/paykeys/{id}/review
Get paykey review details
GET/v1/paykeys/{id}/review
Update a paykey's identity review decision
PUT/v1/paykeys/{id}/refresh_review
ModelsExpand Collapse
ReviewGetResponse = object { data, meta, response_type }
data: object { paykey_details, verification_details }
paykey_details: object { id, config, created_at, 14 more }
id: string

Unique identifier for the paykey.

formatuuid
config: object { processing_method, sandbox_outcome }
processing_method: optional "inline" or "background" or "skip"
One of the following:
"inline"
"background"
"skip"
sandbox_outcome: optional "standard" or "active" or "rejected" or "review"
One of the following:
"standard"
"active"
"rejected"
"review"
created_at: string

Timestamp of when the paykey was created.

formatdate-time
label: string

Human-readable label used to represent this paykey in a UI.

paykey: string

The tokenized paykey value. This value is used to create payments and should be stored securely.

source: "bank_account" or "straddle" or "mx" or 3 more
One of the following:
"bank_account"
"straddle"
"mx"
"plaid"
"tan"
"quiltt"
status: "pending" or "active" or "inactive" or 3 more
One of the following:
"pending"
"active"
"inactive"
"rejected"
"review"
"blocked"
updated_at: string

Timestamp of the most recent update to the paykey.

formatdate-time
balance: optional object { status, account_balance, updated_at }
status: "pending" or "completed" or "failed"
One of the following:
"pending"
"completed"
"failed"
account_balance: optional number

Account Balance when last retrieved

formatint32
updated_at: optional string

Last time account balance was updated.

formatdate-time
bank_data: optional object { account_number, account_type, routing_number }
account_number: string

Bank account number. This value is masked by default for security reasons. Use the /unmask endpoint to access the unmasked value.

account_type: "checking" or "savings"
One of the following:
"checking"
"savings"
routing_number: string

The routing number of the bank account.

minLength9
maxLength9
customer_id: optional string

Unique identifier of the related customer object.

formatuuid
expires_at: optional string

Expiration date and time of the paykey, if applicable.

formatdate-time
external_id: optional string

Unique identifier for the paykey in your database, used for cross-referencing between Straddle and your systems.

institution_name: optional string

Name of the financial institution.

metadata: optional map[string]

Up to 20 additional user-defined key-value pairs. Useful for storing additional information about the paykey in a structured format.

status_details: optional object { changed_at, message, reason, 2 more }
changed_at: string

The time the status change occurred.

formatdate-time
message: string

A human-readable description of the current status.

reason: "insufficient_funds" or "closed_bank_account" or "invalid_bank_account" or 24 more
One of the following:
"insufficient_funds"
"closed_bank_account"
"invalid_bank_account"
"invalid_routing"
"disputed"
"payment_stopped"
"owner_deceased"
"frozen_bank_account"
"risk_review"
"fraudulent"
"duplicate_entry"
"invalid_paykey"
"payment_blocked"
"amount_too_large"
"too_many_attempts"
"internal_system_error"
"user_request"
"ok"
"other_network_return"
"payout_refused"
"cancel_request"
"failed_verification"
"require_review"
"blocked_by_system"
"watchtower_review"
"validating"
"auto_hold"
source: "watchtower" or "bank_decline" or "customer_dispute" or 2 more
One of the following:
"watchtower"
"bank_decline"
"customer_dispute"
"user_action"
"system"
code: optional string

The status code if applicable.

unblock_eligible: optional boolean

Indicates whether this paykey is eligible for client-initiated unblocking. Only present for blocked paykeys. True when blocked due to R29 returns and not previously unblocked, false otherwise. Null when paykey is not blocked.

verification_details: optional object { id, breakdown, created_at, 3 more }
id: string

Unique identifier for the verification details.

formatuuid
breakdown: object { account_validation, name_match }
account_validation: optional object { codes, decision, reason }
codes: array of string
decision: "accept" or "reject" or "review"
One of the following:
"accept"
"reject"
"review"
reason: optional string
name_match: optional object { codes, decision, correlation_score, 4 more }
codes: array of string
decision: "accept" or "reject" or "review"
One of the following:
"accept"
"reject"
"review"
correlation_score: optional number
customer_name: optional string
matched_name: optional string
names_on_account: optional array of string
reason: optional string
created_at: string

Timestamp of when the verification was initiated.

formatdate-time
decision: "accept" or "reject" or "review"
One of the following:
"accept"
"reject"
"review"
messages: map[string]

Dictionary of all messages from the paykey verification process.

updated_at: string

Timestamp of the most recent update to the verification details.

formatdate-time
meta: ResponseMetadata { api_request_id, api_request_timestamp }

Metadata about the API request, including an identifier and timestamp.

api_request_id: string

Unique identifier for this API request, useful for troubleshooting.

formatuuid
api_request_timestamp: string

Timestamp for this API request, useful for troubleshooting.

formatdate-time
response_type: "object" or "array" or "error" or "none"

Indicates the structure of the returned content.

  • "object" means the data field contains a single JSON object.
  • "array" means the data field contains an array of objects.
  • "error" means the data field contains an error object with details of the issue.
  • "none" means no data is returned.
One of the following:
"object"
"array"
"error"
"none"