RekomiRekomiBlogPricing
Rekomi Docs
Rekomi Docs
Welcome to Rekomi
API overviewAuthenticationOAuth 2.0Server-to-server trackingTracking script & window.RekomiTrack leads and signupsNo-code & non-Stripe checkoutsCustom domainConversion currencyCoupon code trackingSub-affiliate recruiting APIWebhooksZapierWhite-label embedMCP serverAPI reference
For developers
|Developers|

Conversion currency

ISO 4217 allowlist, error codes, Stripe normalization, and the home-currency settings endpoint.

Every conversion ingested by Rekomi carries a currency field. The full list of supported codes is below, plus the error response shape when an unsupported code is sent and the developer-side surface for reading or changing the org's home (display) currency.

For the brand-facing concept page (when to change HomeCurrency, how FX normalization works, how payouts are split per currency, how the 1099-NEC handles non-USD earnings), see Multi-currency.

Supported currencies (v1)

31 ISO 4217 codes. Validated server-side on every ingest path.

USD EUR GBP CAD AUD JPY CHF SEK NOK DKK
NZD SGD HKD MXN BRL INR ZAR PLN CZK HUF
RON ILS TRY KRW PHP THB MYR IDR AED SAR
CNY

Codes are normalized to uppercase server-side, so usd and USD are equivalent on the wire. Anything else (lowercase still-not-in-list codes, crypto tickers, currency-substitute tokens like XBT, retired codes) is rejected.

Ingest paths that accept currency

POST /api/tracking/s2s

Server-to-server, HMAC-signed. See S2S tracking for auth + signing.

{
  "externalEventId": "purchase_abc123",
  "affiliateSlug": "jane-recommends",
  "amountCents": 9900,
  "currency": "EUR",
  "customerId": "cus_external_xyz"
}

currency is optional. Omit to default to "USD".

POST /api/tracking/pixel

Browser pixel, public-key + origin allowlist. See Pixel tracking.

{
  "external_event_id": "ORDER_42",
  "amount_cents": 9900,
  "currency": "JPY",
  "email": "buyer@example.com"
}

Same defaulting rules: omit for USD, send a 3-letter ISO code otherwise.

Error response for unsupported currencies

Sent on both ingest endpoints (S2S and pixel) when the code is well-formed but not in the v1 allowlist:

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "error": "unsupported_currency",
  "currency": "XYZ"
}

If the code is malformed (not 3 letters, empty string after trim, contains digits), you get the existing shape:

{ "error": "currency_must_be_3_letters" }

These are distinct on purpose. currency_must_be_3_letters is a malformed-input issue your client should never emit. unsupported_currency is "we recognize this is a real currency code, we just don't have an FX rate for it"; handle by mapping to a supported code on your side, or contact support if you need the allowlist extended.

Curl examples

USD conversion (S2S)

BODY='{"externalEventId":"order_001","affiliateSlug":"jane","amountCents":9900,"currency":"USD"}'
T=$(date +%s)
SIG=$(printf "%s.%s" "$T" "$BODY" | openssl dgst -sha256 -hmac "$REKOMI_SIGNING_SECRET" -hex | awk '{print $2}')

curl -sS https://api.rekomi.com/api/tracking/s2s \
  -H "Authorization: Bearer $REKOMI_API_KEY" \
  -H "X-Rekomi-Signature: t=$T,sig=$SIG" \
  -H "Content-Type: application/json" \
  -d "$BODY"

EUR conversion (S2S)

BODY='{"externalEventId":"order_002","affiliateSlug":"jane","amountCents":8900,"currency":"EUR"}'
T=$(date +%s)
SIG=$(printf "%s.%s" "$T" "$BODY" | openssl dgst -sha256 -hmac "$REKOMI_SIGNING_SECRET" -hex | awk '{print $2}')

curl -sS https://api.rekomi.com/api/tracking/s2s \
  -H "Authorization: Bearer $REKOMI_API_KEY" \
  -H "X-Rekomi-Signature: t=$T,sig=$SIG" \
  -H "Content-Type: application/json" \
  -d "$BODY"

JPY conversion (S2S)

JPY has no minor unit. amountCents is still required, but Rekomi treats the integer as whole yen on display. A 12,000 JPY sale is "amountCents": 12000.

BODY='{"externalEventId":"order_003","affiliateSlug":"jane","amountCents":12000,"currency":"JPY"}'
T=$(date +%s)
SIG=$(printf "%s.%s" "$T" "$BODY" | openssl dgst -sha256 -hmac "$REKOMI_SIGNING_SECRET" -hex | awk '{print $2}')

curl -sS https://api.rekomi.com/api/tracking/s2s \
  -H "Authorization: Bearer $REKOMI_API_KEY" \
  -H "X-Rekomi-Signature: t=$T,sig=$SIG" \
  -H "Content-Type: application/json" \
  -d "$BODY"

Stripe-webhook currency handling

For brands using the Stripe integration, conversion currency comes from the Stripe invoice.payment_succeeded / charge.succeeded event's currency field. Stripe lowercases everything ("usd", "eur"). Rekomi:

  1. Uppercases the code ("usd" → "USD").
  2. Checks it against the same 31-code allowlist used by S2S + pixel.
  3. If supported, stores it on the conversion row.
  4. If unsupported (rare; Stripe supports more currencies than the ECB publishes daily rates for), the conversion is still recorded so payouts can run, but a Sentry warning fires with the org id and the offending code so Rekomi ops can decide whether to extend the allowlist.

This means: Stripe brands cannot accidentally drop conversions by selling in a non-allowlisted currency. S2S and pixel are stricter because the caller controls the field and can validate before sending.

Reading / updating the home currency

There is a settings-side endpoint your application can call to read or set the org's HomeCurrency. Same Authorization: Bearer rk_live_* auth as the rest of the API.

GET /api/settings/home-currency

{
  "homeCurrency": "USD",
  "changedAt": null,
  "canChange": true,
  "supportedCurrencies": [
    "USD", "EUR", "GBP", "CAD", "AUD", "JPY", "CHF", "SEK", "NOK", "DKK",
    "NZD", "SGD", "HKD", "MXN", "BRL", "INR", "ZAR", "PLN", "CZK", "HUF",
    "RON", "ILS", "TRY", "KRW", "PHP", "THB", "MYR", "IDR", "AED", "SAR",
    "CNY"
  ]
}
  • homeCurrency: current setting. "USD" for any org that never explicitly changed it.
  • changedAt: ISO-8601 timestamp of the most recent change, or null if never changed.
  • canChange: true when the caller's plan tier is Pro (or trialing on any tier). false otherwise. Use this to gate UI without making a failing PUT.
  • supportedCurrencies: the 31-code allowlist. Provided so clients don't have to hard-code the list.

PUT /api/settings/home-currency

{ "homeCurrency": "EUR" }

Requires:

  • Owner role on the org (Admin / Manager / Viewer return 403).
  • Pro plan or active trial.
  • A supported currency code.

Response on success:

{
  "homeCurrency": "EUR",
  "changedAt": "2026-05-18T14:22:01Z",
  "canChange": true
}

Error responses:

HTTPerrorCause
400unsupported_currencyCode not in the 31-code allowlist
400currency_must_be_3_lettersMalformed code
402plan_tier_requiredOrg below Pro and not trialing
403(empty)Caller is not Owner of the org

PUTs are idempotent: setting the same currency twice returns 200 both times, and only the first call writes a changedAt + audit-log entry.

See also

  • Multi-currency for brands: concept page, payout splitting, tax-form handling.
  • S2S tracking: server-side ingestion + refund endpoint.
  • Pixel tracking: browser-side ingestion for no-code stacks.
  • Webhooks: payout.created / payout.paid payloads always carry the per-payout currency.
  • Sub-affiliate API: override conversion rows carry the same currency field as the parent sale.

Custom domain

Serve the Rekomi tracking script from your own subdomain so it loads first-party and bypasses tracker-blocking content filters.

Coupon code tracking

Create per-affiliate Stripe promotion codes, attribute conversions on redemption, and clawback refunds automatically.

On this page

Supported currencies (v1)Ingest paths that accept currencyPOST /api/tracking/s2sPOST /api/tracking/pixelError response for unsupported currenciesCurl examplesUSD conversion (S2S)EUR conversion (S2S)JPY conversion (S2S)Stripe-webhook currency handlingReading / updating the home currencyGET /api/settings/home-currencyPUT /api/settings/home-currencySee also