POBO SWIFT Payment

📘

A wallet is required to initiate payment on behalf of a customer. See create crypto wallet for more information.

To initiate a pay-on-behalf-of (POBO) SWIFT payment, either create an external account for the customer or provide the payment details directly.

  1. Create an external account flow:
    1. Create an external account
    2. Create a POBO SWIFT transfer
  2. Provide the payment details directly
    1. Create POBO SWIFT Transfer without an External Account
  3. Monitor transfer status
  4. Webhooks examples

Create an external account flow

1. Create an external account

Provide customerId when creating an external account on behalf of a customer.

See API reference.
curl --request POST \
  --url https://api.sandbox.keyrails.com/api/v1/external-accounts \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer {{AccessToken}}'  \
  --data '{
    "customerId": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "ABC LTD",
    "phone": "+447934758009", 
    "address": {
      "street1": "1 Main Road",
      "street2": "string",
      "postalCode": "string",
      "city": "string",
      "country": "GB"
    },
    "bankName": "asdsad",
    "bankAddress": {
      "street1": "5 Money Lane",
      "street2": "string",
      "postalCode": "10001",
      "city": "Big City",
      "country": "CN" 
    },
    "swift": {
    	"accountNumber": "string", // optional when beneficiaryIban is provided
      "iban": "string", // optional when beneficiaryAccountNumber is provided
      "bic": "ABC123456"
    }
}
'

Response:

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "accountNumberLast4": "string",
  "receiverName": "string",
  "accountName": "string",
  "swiftCode": "string", 
  "iban": "string",
  "createdAtUtc": "2025-05-22T18:04:27.272Z"
}

2. Create a SWIFT Transfer

To expedite the compliance check procedure, you need to upload documents that support the transaction. For instance, if the payment pertains to a trade, you can upload multiple files such as invoice, sender's company registration document and other supporting documents.

See API reference.
curl --request POST \
     --url https://api.sandbox.keyrails.com/api/v1/transfers \
     --header 'accept: application/json' \
     --header 'content-type: application/*+json' \
     --header 'Authorization: Bearer {{AccessToken}}' \
     --data '{
  "customerId": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "source": {
    "currency": "USDC",
    "network": "ethereum",
    "walletId": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  },
  "destination": {
    "currency": "GBP",
    "externalAccountId": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  },
  "purposeOfPayment": "PaymentForGoods",
  "receiverAmount": 15000.00, // this is the amount in destination currency
  "memo": "test payment",
  "documents": [
   "data:image/[type];base64,abdcxxxx",
   "data:image/[type];base64,abdcxxxx"
  ]
}
'

Response:

{
    "id": "43fba2ee-a0b8-40d4-906b-e1f86c9cb4a3",
    "transactionId": "8d5f9f94-eb7b-4d7f-95e8-f649ad10f4fb",
    "status": "New",
    ...
}

Provide the payment details directly

Create a SWIFT Transfer without an External Account

To expedite the compliance check procedure, you need to upload documents that support the transaction. For instance, if the payment pertains to a trade, you can upload multiple files such as invoice, sender's company registration document and other supporting documents.

See API reference.
curl --request POST \
     --url https://api.sandbox.keyrails.com/api/v1/transfers \
     --header 'accept: application/json' \
     --header 'content-type: application/*+json' \
     --header 'Authorization: Bearer {{AccessToken}}' \
     --data '{
    "customerId": "string",
    "source": {
      "currency": "USDC",
      "network": "Ethereum",
      "walletId": "string"
    },
    "destination": {
      "currency": "GBP",
      "receiver": {
        "name": "string",
        "phone": "+447912345678",
        "address": {
          "street1": "string",
          "street2": "string", // optional
          "postalCode": "string", // optional
          "city": "string",
          "state": "string", // optional
          "country": "string"
        }
      },
      "bank": {
        "name": "string",
        "address": {
          "street1": "string",
          "street2": "string", // optional
          "postalCode": "string", // optional
          "city": "string",
          "state": "string", // optional
          "country": "string"
        },
        "accountNumber": "string", // optional - when iban is provided
        "iban": "string", // optional - when accountNumber is provided
        "bic": "string"
      }
    },
    "purposeOfPayment": "PaymentForGoods",
    "receiverAmount": 5000.00, // Amount in destination currency eg. GBP
    "memo": "INV-001",
    "documents": ["data:image/[type];base64,abdcxxxx", "data:image/[type];base64,abdcxxxx"]
}

Response:

{
    "id": "43fba2ee-a0b8-40d4-906b-e1f86c9cb4a3",
    "transactionId": "8d5f9f94-eb7b-4d7f-95e8-f649ad10f4fb",
    "status": "New",
    ...
}

Monitor Transfer Status

See API reference.
curl --request GET \
     --url https://api.sandbox.keyrails.com/api/v1/transactions/{transactionId} \
     --header 'accept: application/json' \
     --header 'content-type: application/*+json' \
     --header 'Authorization: Bearer {{AccessToken}}' \

Response:

The API responds with a transactionId, which can be used to track the transfer.

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "transactionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "status": "New",
  "trackingStatus": "string",
  "trackingReference": "string",
  "currency": "USD",
  "sourceCurrency": "USD",
  "destinationCurrency": "USD",
  "network": "Sepolia",
  "amount": 0,
  "cryptoAmount": 0,
  "transactionFee": 0,
  "appliedFee": 0,
  "totalAmount": 0,
  "comment": "string",
  "memo": "string",
  "purposeOfPayment": "string",
  "country": "string",
   ...
}

Webhooks Examples

Before proceeding, ensure that your webhook configuration is set up. Refer to the setup guide for detailed instructions.

  • Webhook types: Transaction
  • resourceId: References the transaction ID

Processing:

{
  "tenantId": "2711ad4d-2c6b-4238-9f9d-2381d7a6d214",
  "action": "Create",
  "id": "e95503c4-f8bb-4f6b-89d3-42f10307a6bc",
  "resourceId": "b5787a92-82ba-4f09-bacc-02f57ea601ed",
  "resourceType": "Transaction",
  "createdAtUtc": "2025-07-29T13:47:04.7710866Z",
  "changes": {
    "transactionStatus": "Processing"
  }
}

Completed:

{
  "tenantId": "36a6deef-8d5a-4560-b17d-e73f1dd3cd88",
  "action": "Update",
  "id": "4c01fdd9-923d-4ad9-9508-48a39cc85a3b",
  "resourceId": "6470d2bd-89e3-4e10-a3ff-605d820f8da3",
  "resourceType": "Transaction",
  "createdAtUtc": "2025-07-29T14:06:04.1804263Z",
  "changes": {
    "transactionStatus": "Completed"
  }
}

Failed:

{
  "tenantId": "36a6deef-8d5a-4560-b17d-e73f1dd3cd88",
  "action": "Update",
  "id": "44110cf3-05c4-4652-b718-fc0d6475453f",
  "resourceId": "6470d2bd-89e3-4e10-a3ff-605d820f8da3",
  "resourceType": "Transaction",
  "createdAtUtc": "2025-07-29T14:07:01.6713778Z",
  "changes": {
    "transactionStatus": "Failed"
  }
}