# Requests and responses

How every Kustom API writes currencies, minor-unit amounts, dates, locales, countries, strings and identifiers, which locale mismatches are corrected rather than rejected, and how to address a created resource from the identifier it returns.

One set of formats holds across every Kustom API, so a value you build once serializes
correctly everywhere. Amounts are always minor units, dates are always ISO 8601, locales are
always language-plus-country and anything Kustom generated ends in `_id` while anything you
generated ends in `_reference`. Getting these wrong is the single most common cause of a
`400` at checkout.

## Currencies and amounts

Currencies use [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) three-letter codes —
`USD`, `GBP`, `EUR`, `SEK`.

Amounts are integers in the **minor unit** of that currency. Never send a decimal, and never
send a float.

| Currency | Value to send | Means |
| --- | --- | --- |
| `USD` | `1000` | $10.00 |
| `GBP` | `500` | £5.00 |
| `EUR` | `50` | €0.50 |
| `SEK` | `100` | 1.00 kr |

```json
{
  "purchase_currency": "USD",
  "order_amount": 1000
}
```

## Dates and times

Dates use [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) with date, time and timezone
combined. Send UTC unless a field says otherwise.

| Value | Means |
| --- | --- |
| `2015-08-10T07:45:00Z` | 10 August 2015, 07:45:00 UTC |
| `2015-08-10T07:45:00.098Z` | the same instant, with 98 milliseconds |

The exception is `date_of_birth`, which is a plain calendar date in `YYYY-MM-DD` — no time,
no timezone.

## Locales and countries

| Field kind | Standard | Examples |
| --- | --- | --- |
| Locale | [RFC 5646](https://en.wikipedia.org/wiki/IETF_language_tag) language tag — two-letter language, two-letter country | `en-us`, `en-gb`, `sv-se` |
| Country | [ISO 3166 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) | `us`, `gb`, `se` |

```json
{
  "locale": "en-us",
  "purchase_country": "US"
}
```

A locale that doesn't go with the purchase country is accepted, not rejected: Checkout falls
back to `en` for a language it doesn't support and to the order's purchase country for an
unrecognized region. Only a malformed tag — anything that isn't two letters, optionally followed
by two-letter subtags such as a region — is rejected outright.

The pair that *is* validated against your merchant account is `purchase_country` and
`purchase_currency`. A currency you aren't configured for is a `400`, not a fallback.

## Strings and encoding

- Send UTF-8. Everything Kustom accepts is UTF-8 encoded.
- Length limits are per field, so check the field's own description. Most fields reject a
  value over their limit with a `400`, but a few Checkout order-line fields are truncated
  instead: `name` beyond 255 characters and `quantity_unit` beyond 8.

## Identifiers — `_id` versus `_reference`

The suffix tells you who minted the value, which tells you which one you may look a resource
up by.

| Suffix | Generated by | Example |
| --- | --- | --- |
| `_id` | Kustom | `order_id`, `capture_id`, `refund_id` |
| `_reference` | you or your partner | `merchant_reference1`, `payment_reference` |

Kustom identifiers are opaque. Do not parse them, do not assume a length or a character set
and do not assume the format is stable across services.

## Addressing a created resource

Store the identifier a create returns — `order_id`, `capture_id`, `refund_id` — and address the
resource by it. That identifier is what every later read and update is keyed on, and it's what
you'll be matching against your own records anyway.

```http
POST /checkout/v3/orders

HTTP/1.1 201 Created
Location: https://api.kustom.co/checkout/v3/orders/1f5bf8bd-8e2a-4b93-9f2c-8d1a3b6c9e04
```

A `201` also carries a `Location` header: the resource's absolute URL, as above. It encodes
nothing the `order_id` doesn't, so key on the id and build the URL from it rather than storing
the header.

## Related

- [Reading an error body when a value is rejected](/api/errors/) — the object a malformed request comes back as
- [Attaching your own references and data](/basics/conventions/merchant-data/) — the `_reference` and `merchant_data` fields
- [Picking the right host for an environment](/api/authentication/) — the base URL these paths hang off
- [Checking a field's exact type and length](/api/checkout/) — the generated per-endpoint schemas
