CorebanqCorebanq Developer Docs
FXv2

List FX tariffs

Lists FX tariffs in the shared list envelope. Items are transform.FxTariffResponse, which does NOT carry is_default — the v1 CRUD shape does. Results are limited to the caller's permitted records: the service passes a real caller id and RbacRecordType into the shared getAll path, which folds the permitted ids into the query. SEARCH FILTERS. Every search.* parameter below is one filter on one column, and the list is the whole set the route accepts. Append an operator to compare instead of match — search.{field}.{op}, op one of eq, ne, gt, gte, lt, lte, in, nin, like, start_with, end_with; with no suffix the operator is eq. in and nin take a comma-separated list. like, start_with and end_with are case-insensitive ILIKE. search.{field}.eq=null and search.{field}.ne=null test for NULL; any other operator with an empty value is 400 query.operator_requires_value. A STRING VALUE IS SILENTLY REWRITTEN BEFORE IT REACHES THE QUERY. sanitizeStringValue drops every character that is not a letter, a digit, or one of . / @ - _ and space, and it never reports an error — so search.provider=A*B filters on AB and answers 200, not 400. A value that parses as a timestamp is passed through instead of stripped. Which rejections are 400 and which are 500 is set out under the 400 and 500 responses; the split is not the one a caller would expect. A DATE-TYPED FILTER IS TRUNCATED TO THE DAY. Where the route's field map types a column as date, normalizeSearchValueByFieldType rewrites the value as YYYY-MM-DD at midnight UTC before it reaches SQL, so a time component on such a filter is discarded without a word. Those parameters carry format: date below; the format: date-time ones are compared as sent.

GET
/v2/fx/tariffs

Authorization

bearerAuth
AuthorizationBearer <token>

In: header

Query Parameters

limit?integer
offset?integer
sort?string

Comma-separated sort expression over the searchable fields listed below, each optionally prefixed with - for descending. A name outside that set is 400 query_m.invalid_sort_field.

filter?string

JSON-encoded filter criteria; invalid JSON is rejected with 400.

search_text?string

Free-text search. Also accepted as search.

stack?string

Group by this field; data becomes an object keyed by its value. Accepts only the searchable names listed below, optionally with a leading - and a [format] suffix; anything else is 400 query_m.invalid_field.

distinct?string
search.name?string
search.description?string
search.fallback_tariff_id?string
search.id?string
search.created_at?string
search.created_by?string
search.modified_at?string
search.modified_by?string
search.active?boolean

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v2/fx/tariffs"
{
  "total": 0,
  "total_unfiltered": 0,
  "metadata": {},
  "keys": [
    "string"
  ],
  "has_more": true,
  "data": [
    {
      "name": "string",
      "description": "string",
      "fallback_tariff_id": "e4b6bec8-3c7c-45ce-b8c3-85abac4ed74b",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "created_at": "2019-08-24T14:15:22Z",
      "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
      "modified_at": "2019-08-24T14:15:22Z",
      "modified_by": "e8d4374d-93a1-4e98-a6c6-fdcf00c5059f",
      "active": true,
      "metadata": {}
    }
  ]
}
{
  "status": 409,
  "message": "Spread rule overlaps an existing rule",
  "code": "fx_m.spread_overlap",
  "class": "business",
  "retryable": false,
  "details": [
    {
      "field": "percent_fee",
      "rule": "lte",
      "param": "1",
      "message": "string"
    }
  ]
}
{
  "status": 409,
  "message": "Spread rule overlaps an existing rule",
  "code": "fx_m.spread_overlap",
  "class": "business",
  "retryable": false,
  "details": [
    {
      "field": "percent_fee",
      "rule": "lte",
      "param": "1",
      "message": "string"
    }
  ]
}
{
  "status": 409,
  "message": "Spread rule overlaps an existing rule",
  "code": "fx_m.spread_overlap",
  "class": "business",
  "retryable": false,
  "details": [
    {
      "field": "percent_fee",
      "rule": "lte",
      "param": "1",
      "message": "string"
    }
  ]
}
{
  "status": 429,
  "message": "Rate limit for 203.0.113.7 to GET:/v1/fx/rates exceeded.",
  "code": "rate_limits_m.exceeded",
  "class": "temporary",
  "retryable": true
}
{
  "status": 409,
  "message": "Spread rule overlaps an existing rule",
  "code": "fx_m.spread_overlap",
  "class": "business",
  "retryable": false,
  "details": [
    {
      "field": "percent_fee",
      "rule": "lte",
      "param": "1",
      "message": "string"
    }
  ]
}

{
  "overall_status": "unhealthy",
  "message": "Service is shutting down",
  "timestamp": "2026-08-27T15:04:05Z"
}

GETPreview spread rates

Preview BUY/SELL rates that would be applied for a given currency pair, tariff, and MID rate

GETList FX tariff fee ranges

Lists fee ranges in the shared list envelope, in INTEGER MINOR units. Results are limited to the caller's permitted records: the service passes a real caller id and RbacRecordType into the shared getAll path, which folds the permitted ids into the query. SEARCH FILTERS. Every search.* parameter below is one filter on one column, and the list is the whole set the route accepts. Append an operator to compare instead of match — search.{field}.{op}, op one of eq, ne, gt, gte, lt, lte, in, nin, like, start_with, end_with; with no suffix the operator is eq. in and nin take a comma-separated list. like, start_with and end_with are case-insensitive ILIKE. search.{field}.eq=null and search.{field}.ne=null test for NULL; any other operator with an empty value is 400 query.operator_requires_value. A STRING VALUE IS SILENTLY REWRITTEN BEFORE IT REACHES THE QUERY. sanitizeStringValue drops every character that is not a letter, a digit, or one of . / @ - _ and space, and it never reports an error — so search.provider=A*B filters on AB and answers 200, not 400. A value that parses as a timestamp is passed through instead of stripped. Which rejections are 400 and which are 500 is set out under the 400 and 500 responses; the split is not the one a caller would expect. A DATE-TYPED FILTER IS TRUNCATED TO THE DAY. Where the route's field map types a column as date, normalizeSearchValueByFieldType rewrites the value as YYYY-MM-DD at midnight UTC before it reaches SQL, so a time component on such a filter is discarded without a word. Those parameters carry format: date below; the format: date-time ones are compared as sent.