# Requests

Source: <https://docs.gjold.com/v2/requests>

A request names the object it acts on in its URL, and says what to do with it in its method and its body, a JSON object.

## Environments

| Host | Environment |
|---|---|
| `api.gjold.com` | Production, where payers pay for real. |
| `api.gjold.dev` | The test environment, for developing integrations, where no money moves. |

The two are not connected: an account, a key, or an ID on one means nothing on the other. Only we create accounts in the test environment: [write to us](mailto:support@gjold.com) and say what you need one for.

## URLs

Every object has a URI, which names its shop, the database it is in, and its ID there:

```
{shopid}:{db}:{id}
```

A request's URL is `https://api.gjold.com/v2/`, then as much of a URI as the request needs, then the action, if the request has one. Without an action, the method says what the request does, as a `DELETE` deletes the object:

```
https://api.gjold.com/v2/{shopid}:{db}/{action}
https://api.gjold.com/v2/{shopid}:{db}:{id}/{action}
https://api.gjold.com/v2/{shopid}:{db}:{id}
```

A URL that fits no request is answered `404 Not Found`, and a known URL with the wrong method `405 Method Not Allowed`.

### IDs

| Database | Its IDs |
|---|---|
| `pay` | Payment links. A link's ID is the `"id"` that [Create payment link](https://docs.gjold.com/v2/payment-links/create#response) answers with: 12 to 48 letters and digits. |
| `trn` | Transactions, which a paid link or a charge of a subscriber creates. A transaction's ID is its `"id"` in [seq](https://docs.gjold.com/v2/synchronization/seq)'s changes, or in the answer to [Charge subscriber](https://docs.gjold.com/v2/subscribers/charge#response). |
| `sub` | Subscribers. A subscriber's ID is its `"id"` in seq's changes. |
| `seq` | The changes themselves, by number: see [Seq](https://docs.gjold.com/v2/synchronization/seq). |

Your shop ID is in the dashboard. Shop, transaction, and subscriber IDs are positive integers, written in decimal without leading zeros, and never reused. A shop's transactions are numbered from 1 in the order they were created, and so are its subscribers. Store an ID as a 64-bit integer, or as a string.

## Request bodies

A `POST` request has a body: one JSON object, encoded as UTF-8, of at most 32 KiB. We don't read `Content-Type`, but send `application/json`, which is what it is. A request without fields to send, such as a void, sends `{}`.

The body must be valid JSON. If it isn't, the request fails with `400 invalid json in {where}: {why}`, where `{where}` is the path of the field at fault, as in `items[1].total`, or `json root object` for the body as a whole. See [Errors](https://docs.gjold.com/v2/errors#invalid-json).

- **Unknown fields** are ignored, so that a request written for a later version of the API, or with a field that you misspelled, still goes through. Check your spelling against the field tables.
- **Types** are as each field table gives them. A field of another type is an error, and so is `null`: leave the field out instead.
- **Strings** may contain any Unicode text, which we clean up before we store it: each white space character, such as a tab or a newline, becomes a space, other control characters are removed, and spaces at the ends are trimmed. A string that is empty after that is the same as no string at all.
- **Integers** are JSON numbers without a fraction or an exponent, so `2`, not `2.0` or `"2"`.
- **Amounts** are strings, as `"99.95 DKK"`, never JSON numbers. See [Amounts](https://docs.gjold.com/v2/amounts).

## Responses

A request that succeeds is answered with `200 OK` and a JSON object, which is `{}` for the requests that only act, such as a capture. Its `Content-Type` is `application/json`. A request that fails is answered with another status and a line of text. See [Errors](https://docs.gjold.com/v2/errors).

Every response has these headers:

| HTTP header | Why |
|---|---|
| `Cache-Control: no-store` | No answer is to be cached, by you or anything in between. |
| `Strict-Transport-Security: max-age=63072000` | Browsers and clients that honour it use HTTPS only, for two years. |
| `X-Content-Type-Options: nosniff` | The `Content-Type` is what it says. |

## Compatibility

The API's version is in its URL, `/v2/`. Within a version, we may add to the API, but not change or take away:

- We may add requests, optional request fields, response fields, and new values of fields that list their values, such as a change's `"type"`, a transaction's `"act"`, a card's `"brand"`, or a transaction's `"services"`. Write your client to skip what it doesn't know.
- We may add error messages, and reword them, but for the ones to branch on: a `402`'s first word, `transient` or `permanent`, and a `409`'s whole message, as [Errors](https://docs.gjold.com/v2/errors#status-codes) lists them. Branch on the status, and on those.
- We don't remove or rename a field, change its type or meaning, or make an optional field required.

A change that breaks these rules goes in a new version, with its own URL, beside the old one.
