Saved Contacts
Saved Contacts store reusable payment instructions for Direct Transfers and Auto Convert Routes. Build their displayFields from the selected route’s metadata.
Required owner, bank, wallet, reference, and memo fields vary by currency and payment rail. Do not keep a separate hardcoded form for each rail.
Create or update a contact
/saved-contacts/v1 Omit id to create a contact. Include an existing contact id to update it.
Crypto wallet
{
"alias": "Treasury USDC wallet",
"isSavedByUser": true,
"instruction": {
"kind": "SavedContact",
"paymentRail": "Base",
"currency": "Usdc",
"displayFields": [
{
"identifier": "PrimaryIdentifier",
"label": "Wallet address",
"value": "0x123456789abcdef0123456789abcdef01234567",
"canCopy": true
}
]
}
} SEPA individual account
{
"alias": "Alex EUR account",
"isSavedByUser": true,
"instruction": {
"kind": "SavedContact",
"paymentRail": "Sepa",
"currency": "Eur",
"displayFields": [
{
"identifier": "PrimaryIdentifier",
"label": "IBAN",
"value": "ES7921000813610123456789",
"canCopy": true
},
{
"identifier": "AccountOwnerType",
"label": "Beneficiary type",
"value": "Individual",
"canCopy": false
},
{
"identifier": "AccountOwnerFirstName",
"label": "First name",
"value": "Alex",
"canCopy": false
},
{
"identifier": "AccountOwnerLastName",
"label": "Last name",
"value": "Rivera",
"canCopy": false
}
]
}
} SEPA business account
Replace the individual owner fields with:
[
{
"identifier": "AccountOwnerType",
"label": "Beneficiary type",
"value": "Business",
"canCopy": false
},
{
"identifier": "AccountOwnerBusinessName",
"label": "Business name",
"value": "Example Company S.L.",
"canCopy": false
}
] Expected response:
{
"contact": {
"id": "123e4567-e89b-12d3-a456-426614174001",
"alias": "Treasury USDC wallet",
"isSavedByUser": true,
"instruction": {
"kind": "SavedContact",
"paymentRail": "Base",
"currency": "Usdc",
"displayFields": [
{
"identifier": "PrimaryIdentifier",
"label": "Wallet address",
"value": "0x123456789abcdef0123456789abcdef01234567",
"canCopy": true
}
],
"notices": []
}
}
} List compatible contacts
/saved-contacts/v1 For a simple currency and rail filter:
curl https://api-preview.bridflow.com/saved-contacts/v1 --request QUERY --header 'Content-Type: application/json' --header 'Authorization: Basic <BASE64(uuid:password)>' --header 'AccountId: 123e4567-e89b-12d3-a456-426614174000' --data '{
"currency": "Usdc",
"paymentRail": "Base",
"isSavedByUser": true
}' When selecting a contact for a route, also send the complete route and set routeSide to Source or Destination. This lets the backend filter contacts by the actual route contract instead of currency and rail alone.
You can also send savedContactIds to resolve a known set of contacts.
Field identifiers
Common identifiers include:
PrimaryIdentifier: wallet address, IBAN, account number, or the rail’s main identifier.SecondaryIdentifier: routing number or another paired identifier.AccountOwnerType,AccountOwnerFirstName,AccountOwnerLastName, andAccountOwnerBusinessName.RecipientNameandInstitutionName.ReferenceandMemo, only when returned by route metadata.
Validation rules
- Keep identifiers distinct; do not merge IBAN, CLABE, account number, and wallet address into one normalized value.
- Validate a blockchain address for its selected network before submission.
- Do not add or silently change a memo. A memo that is not supported by the route must be omitted.
- Keep provider ids and opaque route fields out of user-facing labels.
- On an unsupported-route error, refresh discovery and metadata before rebuilding the form.