Skip to main content

Step 7: exchange currencies within a budget

As well as moving funds from one budget to another, you can exchange funds directly within a single budget. To do so, you first need to create a quote. You’ll then use the IDs received in the response to create an order.

Step 7A: create a quote

First, let’s create a quote to exchange 100 GBP to EUR. All quotes expire after 12 seconds.
By default, in production, you can only use this request during trading hours and you’ll receive live rates. In sandbox, you can use this request 24/7. However, the rates may be a couple of minutes behind current live rates.
curl -i -X POST 'https://api-sandbox.equalsmoney.com/v2/orders/quote?accountId={accountId}' \
  -H 'Authorization: ApiKey {apiKey}' \
  -H 'Content-Type: application/json' \
  -d '{
    "sourceCurrency": {
      "amount": 100,
      "currency": {
        "budgetId": "{budgetId}",
        "currencyCode": "GBP"
      }
    },
    "targetCurrency": {
      "currency": {
        "budgetId": "{budgetId}",
        "currencyCode": "EUR"
      }
    },
    "settlementDate": "2023-12-01T21:41:50Z",
    "type": {
      "from": "balance",
      "to": "payment"
    }
  }'
If your request is successful, you’ll receive a 200 response containing an orderId and quoteRequestId.
{
  "quoteRequestId": "4c14643c-072d-468a-81f0-791f4aca84ee-100-109.7222",
  "settlement": {
    "date": "20231201",
    "price": {
      "amount": 100,
      "currency": "GBP"
    },
    "charges": {
      "fee": 0
    }
  },
  "quote": {
    "rate": 1.0972222222,
    "inverseRate": 0.9113924051,
    "fromGbpAmount": 100,
    "from": {
      "amount": 100,
      "currency": "GBP"
    },
    "to": {
      "amount": 109.72,
      "currency": "EUR"
    },
    "direction": "1"
  },
  "orderId": "FPLZQVE5G2ZZKS"
}

Step 7B: create an order

Now that we have an order ID and quote request ID, we can create an order and perform the currency exchange.
curl -i -X POST 'https://api-sandbox.equalsmoney.com/v2/orders/trade?accountId={accountId}' \
  -H 'Authorization: ApiKey {apiKey}' \
  -H 'Content-Type: application/json' \
  -d '{
    "orderId": "{orderId}",
    "quoteRequestId": "{quoteRequestId}"
  }'
If your request is successful, you’ll receive a 200 response.
{
  "orderId": "FPLZQVE5G2ZZKS",
  "bank": "BANK",
  "settlement": {
    "date": "20231201",
    "price": {
      "amount": 100,
      "currency": "GBP"
    },
    "charges": {
      "fee": 0,
      "margin": 0,
      "other": 0
    }
  },
  "trade": {
    "rate": 1.0972222222,
    "inverseRate": 0.9113924051,
    "from": {
      "amount": 100,
      "currency": "GBP"
    },
    "to": {
      "amount": 109.72,
      "currency": "EUR"
    }
  }
}
If you’re using the production environment, you’ll also receive a BoxDebited webhook and a BoxCredited webhook. Note that these might not be received in that order.
These webhooks won’t be generated in sandbox.
BoxDebited
{
  "body": {
    "accountId": "F12345",
    "boxTransactionId": 8622112,
    "budgetId": "42082c6b-4ab2-4bf6-b71f-287ge74a66c3",
    "budgetName": "Marketing",
    "identification": "5***",
    "institutionAddress": null,
    "institutionBic": "231884",
    "orderId": "E7PD93VMX3MC",
    "paymentMethod": "UK.OBIE.BalanceTransfer",
    "reference": "",
    "schemeName": "UK.OBIE.SortCodeAccountNumber",
    "settlementPriceAmount": 100,
    "settlementPriceCurrency": "GBP",
    "source": "orders",
    "ledgerBalance": "19.99",
    "sequentialId": "10",
    "valueDateTime": "2024-04-30T06:26:17.297Z",
    "messageId": "f10bf4e9-bf1a-49e0-b10a-a461bf5659f8",
    "webhookEventTypeName": "BoxDebited"
  }
}
BoxCredited
{
  "body": {
    "accountId": "F12345",
    "budgetId": "4db84122-9c4e-4607-98f7-84b2bbe02daf",
    "source": "orders",
    "identification": "12345678",
    "institutionBic": "231884",
    "institutionAddress": null,
    "schemeName": "UK.OBIE.SortCodeAccountNumber",
    "reference": "REF 123456",
    "remitterAddress": null,
    "remitterName": "Sally Smith",
    "budgetName": "Marketing",
    "settlementPriceAmount": 109.72,
    "settlementPriceCurrency": "EUR",
    "paymentMethod": "UK.OBIE.BalanceTransfer",
    "boxTransactionId": 1234567,
    "ledgerBalance": "19.99",
    "sequentialId": "10",
    "valueDateTime": "2024-04-30T06:26:17.297Z",
    "messageId": "b04b2d4a-0ae7-4125-9389-15bb6d47645c",
    "webhookEventTypeName": "BoxCredited"
  }
}

What if it goes wrong?

If you try to trade with an expired quote (quotes expire after 12 seconds), you’ll need to create a new quote and try again. Make sure to use the orderId and quoteRequestId from your most recent quote response. If the budget doesn’t have sufficient funds in the source currency, the trade will fail. Make sure your budget is funded before attempting a currency exchange.