✨ SEPA Payouts Quickstart

Get started with Circle Payments API and send your first wire payout in just a few minutes!

The Circle Payouts API allows you to send SEPA payouts from stablecoin balances you control to your end users' bank accounts in 35+ countries.

1. Get an API key

The Circle Payouts API uses API keys as the mechanism to authenticate client requests. The API key must be set in the Authorization header of the request sent from your backend server. The format of the header is Bearer secret-key-value.

Learn more about authenticating API calls here.

To obtain an API key for the sandbox environment, simply create an account and generate a new key in settings - it only takes a few seconds.


Get an API key

Once you have generated your API key, record it in a secure place.

2. Decide Where to Send Funds From

You can choose to originate a payout from either your master wallet or any other wallet you have control over.

If you are using an omnibus account model where all your funds reside on your master wallet then using it to fund payouts makes complete sense. If you don't provide a source object when using the create payout endpoint, we will attempt to fund the payout from your master wallet.

If you have sub-wallets representing individual users or any other type of structure and you wish to use one of them as source for the payout, then determine the id of the desired wallet and specify it on the source object when using the create payout endpoint.

📘

Identity Verification

If the wallet originating a payout is associated to one of your customers, then issuing a payout from it requires end customer identification. Please reach out to support to understand the options available to you.

📘

Fees

Irrespective of the funding / source wallet scenario chosen, the fee associated with the payout is always deducted from your master wallet.

3. Fund Your Source Wallet

Once you have determined which wallet will fund your payout, make sure you have enough funds on it. You can learn more about different funding options here.

4. Create the Bank Account You Will Send the Payout To

Now make an API call to create the bank account you intend to send the payout to by using the create bank account for SEPA transfers endpoint. Use your API key from step 1.

# Replace ${YOUR_API_KEY} with the API key obtained on step 1
curl -H 'Accept: application/json' \
    -H 'Content-type: application/json' \
    -H "Authorization: Bearer ${YOUR_API_KEY}" \
    -X POST --url https://api-sandbox.circle.com/v1/banks/sepa \
    --data '
  {
    "idempotencyKey": "6ae62bf2-bd71-49ce-a599-165ffcc33680",
    "iban": "DE31100400480532013000",
    "billingDetails": {
      "name": "Satoshi Nakamoto",
      "city": "Dublin",
      "country": "IE",
      "line1": "1 Dublin Street",
      "postalCode": "D01 AY67"
    }
  }
  '

You should receive a response like below.

{
  "data": {
    "id": "a6ba73a8-cc77-46c5-bbbc-ce7a97ecb372",
    "status": "pending",
    "description": "Bank of Ireland ****0010",
    "trackingRef": "CIR13FB13A",
    "fingerprint": "eb170539-9e1c-4e92-bf4f-1d09534fdca2",
    "billingDetails": {
      "name": "Satoshi Nakamoto",
      "city": "Dublin",
      "country": "IE",
      "line1": "1 Dublin Street",
      "postalCode": "D01 AY67"
    },
    "createDate": "2020-04-10T02:13:30.000Z",
    "updateDate": "2020-04-10T02:13:30.000Z"
  }
}

5. Send the Payout

Now that your source wallet has funds and you have created a bank account to transfer funds to, you can use the [create payout endpoint](ref:payouts-payouts-create to initiate the transfer of funds.

If you are transferring funds from your master wallet, you don't need to supply a source object. The request would look like below.

📘

Transfers will initiate at 9:30 AM EST (3:30 PM CET) Monday - Friday excluding TARGET days. Foreign exchange rates will be determined when the transfer is initiated.

# Replace ${YOUR_API_KEY} with the API key obtained on step 1
# Replace ${BANK_ACCOUNT_ID} with the id of the bank account you created earlier
curl -H 'Accept: application/json' \
    -H 'Content-type: application/json' \
    -H 'Authorization: Bearer ${YOUR_API_KEY}' \
    -X POST --url https://api-sandbox.circle.com/v1/payouts \
    --data '
  {
    "idempotencyKey": "ff9d668a-ccde-48c3-82fd-8deb2a6f7c28",
    "destination": {
      "type": "sepa",
      "id": "${BANK_ACCOUNT_ID}"
    },
    "amount": {
      "currency": "USD",
      "amount": "150.00"
    },
    "metadata": {
      "beneficiaryEmail": "[email protected]"
    }
  }
  '

If you are transferring funds from an arbitrary wallet, they you need to identify it in the source object like below.

# Replace ${YOUR_API_KEY} with the API key obtained on step 1
# Replace ${WALLET_ID} with the id of the wallet that will originate the transfer
# Replace ${BANK_ACCOUNT_ID} with the id of the bank account you created earlier
curl -H 'Accept: application/json' \
    -H 'Content-type: application/json' \
    -H 'Authorization: Bearer ${YOUR_API_KEY}' \
    -X POST --url https://api-sandbox.circle.com/v1/payouts \
    --data '
  {
    "idempotencyKey": "ff9d668a-ccde-48c3-82fd-8deb2a6f7c28",
    "source": {
      "type": "wallet",
      "id": "${WALLET_ID}"
    },
    "destination": {
      "type": "sepa",
      "id": "${BANK_ACCOUNT_ID}"
    },
    "amount": {
      "currency": "USD",
      "amount": "150.00"
    },
    "metadata": {
      "beneficiaryEmail": "[email protected]"
    }
  }
  '

In either case, you should receive a response like below.

{
  "data":{
    "id":"2f0d9c44-c86d-4c1a-a33c-d436b8148879",
    "sourceWalletId":"1000005019",
    "createDate":"2020-07-27T07:59:09.350Z",
    "updateDate":"2020-07-27T07:59:09.350Z",
    "destination":{
      "type":"sepa",
      "id":"a6ba73a8-cc77-46c5-bbbc-ce7a97ecb372",
      "name":"Bank of Ireland ****0010",
    },
    "amount":{
      "amount":"150.00",
      "currency":"USD"
    },
    "status":"pending"
  }
}

🎉 Congrats, you sent your first payout to a bank account!

📘

Automated FX

Since SEPA transfers are denominated in EUR, Circle will be automatically converting funds to EUR before initiating the transaction. The amount obtained after FX will be reflected eventually in "toAmount" field in the payout response object.

📘

Status of the Payout

The initial status of a payout is pending. You can obtain the most recent status of your payout by using the get payout endpoint.

Once the payout has been processed by Circle the status will move to complete and a tracking reference code will become available at the trackingRef property. If the payout failed to be sent, then the status will be updated to failed and you should look for a failure reason on the errorCode property.

6. Failures and FX Adjustments

If a payout fails it will go through two instances of foreign exchange (FX) from USD to EUR and back from EUR to USD. This opens the door to rates changing which will result in the returned USD amount being lower or higher in value. In this scenario you can use the adjustments object within the payouts resource to understand what that increased (credited) or decreased (debited) amount is.

Example: If you were to send a payout for $100 that failed and returned for $101 this would be represented as shown in the below example.

{
  "data": {
    "amount": {
      "amount": "100.00",
      "currency": "USD"
    },
    "status": "failed",
    "adjustments": {
      "fxCredit": {
        "amount": "1.00",
        "currency": "USD"
      },
      "fxDebit": {
        "amount": "0.00",
        "currency": "USD"
      }
    }
  }
}

7. Ready for the next step?

By sending a payout, you have covered one of the key primitives of the Circle Payouts API.

If you are in advanced stages of experimenting with our APIs and want to plan moving to production, please start by applying for a Circle Account and subsequently reach out to sales. We'll be happy to walk you through to the next steps.

We can't wait to see what you are going to build!