# Authentication

Source: <https://docs.gjold.com/v1/authentication>

Every request authenticates with an API key, sent with HTTP Basic authentication. A key belongs to a shop, and may make only the requests it has permission for.

## The Authorization header

Send the key as the credentials of [HTTP Basic authentication](https://www.rfc-editor.org/rfc/rfc7617), base64-encoded:

```
Authorization: Basic base64({apikey})
```

A key contains a colon, which separates the shop ID from the secret, as Basic authentication separates a user name from a password. So curl's `-u {apikey}` sends it as it is, and so does any HTTP library that takes a user name and a password: give it the shop ID as the user name and the secret as the password.

There is no other way to authenticate: no key in the URL or the body, and no cookies.

## API keys

A key is your shop ID, a colon, and the key's secret:

```
{shopid}:{secret}
```

The key names the shop, so a v1 URL has no shop ID in it: every request acts on the key's shop. A shop can have several keys, each with its own permissions.

Keys of other forms, such as v2's user keys, don't work in v1.

Keep a key's secret on your server. A key in a browser or an app can be read by anyone who has the page or the app, and used to capture, refund, and charge as you.

## Permissions

A key has permission for some or all of these, and a request that its key lacks permission for fails:

| Permission | Requests |
|---|---|
| `payid` | [Create payment link](https://docs.gjold.com/v1/payment-links/create), [Create subscriber](https://docs.gjold.com/v1/subscribers/create), and [Renew subscriber](https://docs.gjold.com/v1/subscribers/renew), which all create a link |
| `seq` | [Seq](https://docs.gjold.com/v1/synchronization/seq) |
| `capture` | [Capture transaction](https://docs.gjold.com/v1/transactions/capture) |
| `refund` | [Refund transaction](https://docs.gjold.com/v1/transactions/refund) |
| `charge` | [Charge subscriber](https://docs.gjold.com/v1/subscribers/charge) |

A key for a server that only creates links and reads seq needs nothing more, and can't refund if it leaks.

## Pings

A shop has one ping URL, which you set in the dashboard, and gets a [ping](https://docs.gjold.com/v1/synchronization/ping) there whenever something in it changes. The ping is signed with one of the shop's API keys, as [Ping](https://docs.gjold.com/v1/synchronization/ping) describes.

## Errors

A request whose key is missing, wrong, or lacks permission is answered with:

```
HTTP/1.1 401 Unauthorized
Content-Type: text/plain

Unauthorized
```

It is the same, whatever the reason, so that it tells an attacker nothing:

- The `Authorization` header is missing, or is not `Basic`.
- The shop has no key with that secret.
- The key lacks permission for the request.

A key that is not a shop ID and a colon at all, such as one that is not valid base64, or a v2 key, is answered `404 Not Found`, as is a URL that fits no request.

Don't retry a `401`: it will fail the same way until the key or its permissions change. We check the key before we read the body, so a `401` means that nothing was done.
