# Authentication with an API key

Source: https://checkslip.com/en/docs/authentication

Every request to the Checkslip API needs your API key. Create keys on the API keys page of the web app.

## Send the API key

Put the key in the Authorization header as a Bearer token on every request. Checkslip keys start with csk_ and go over HTTPS only.

```
Authorization: Bearer csk_…
```

**cURL**

```bash
curl https://api.checkslip.com/api/slips/lookup \
  -H "Authorization: Bearer $CHECKSLIP_API_KEY" \
  -H "Idempotency-Key: order-1042-slip-1" \
  -H "Content-Type: application/json" \
  -d '{"qr":"00330006000001010306902126302105340875102TH9104F86F"}'
```

**Node.js**

```javascript
const res = await fetch("https://api.checkslip.com/api/slips/lookup", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CHECKSLIP_API_KEY}`,
    "Idempotency-Key": "order-1042-slip-1",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    qr: "00330006000001010306902126302105340875102TH9104F86F",
  }),
});
const data = await res.json();
```

**Python**

```python
import os

import requests

res = requests.post(
    "https://api.checkslip.com/api/slips/lookup",
    headers={
        "Authorization": f"Bearer {os.environ['CHECKSLIP_API_KEY']}",
        "Idempotency-Key": "order-1042-slip-1",
    },
    json={
        "qr": "00330006000001010306902126302105340875102TH9104F86F",
    },
)
data = res.json()
```

## What a key may do

When you create a key you choose what it may do. Give each key only the scopes your system uses.

| Scope | What it allows |
| --- | --- |
| `slip:lookup` | Send a QR or trans_ref to fetch the transfer the bank has on record (uses credit when found) |
| `slip:read` | Read the account's lookup history |
| `credit:read` | Read the credit balance, its expiry date and the credit history |
| `webhook:read` | Read webhook endpoints and delivery history |
| `webhook:manage` | Create, edit and delete webhook endpoints (reading not included) |
| `audit:read` | Read the account's API request log and change log |
| `audit:export` | Create and download evidence files (needs audit:read too) |
| `billing:read` | Read orders, receipts, credits and receipt details (including the tax ID) |
| `billing:write` | Edit the details printed on receipts issued from now on (a key cannot top up credits) |
| `usage:read` | Read the account's credit usage |

- Each scope stands alone; none includes another. For example, slip:lookup does not give slip:read.
- A key's scopes cannot be changed after it is created. For other scopes, create a new key.

## Keep keys safe

- The web app shows the whole key once, when you create it. Copy it right away; if you lose it, create a new key.
- Keep keys on your server, for example in environment variables or a secrets store. Never put one in a mobile app, web page code or a repository.
- Use separate keys for separate systems or environments, so you can revoke one without touching the others.
- An account can have up to 10 keys in use (revoked or expired keys do not count).

## Replace a key

1. Create a new key in the web app
2. Switch your system to the new key
3. Revoke the old key

A revoked or expired key stops working within 30 seconds (usually at once) and cannot be turned back on.

## When a key has a problem

Requests answered with these errors use no credit. Every code is listed in [Error codes](https://checkslip.com/en/docs/errors)

| Code | HTTP | Meaning |
| --- | --- | --- |
| [`UNAUTHENTICATED`](https://checkslip.com/en/problems/unauthenticated) | 401 | No key, or a key that cannot be used (malformed, revoked, expired or unknown); which one is not said, for safety |
| [`FORBIDDEN`](https://checkslip.com/en/problems/forbidden) | 403 | The key does not have the scope this request needs |
| [`NOT_VIA_API_KEY`](https://checkslip.com/en/problems/not-via-api-key) | 403 | This can only be done in the web app, for example managing API keys or topping up credit |
| [`ACCOUNT_SUSPENDED`](https://checkslip.com/en/problems/account-suspended) | 403 | The account is suspended for now |
| [`RATE_LIMITED`](https://checkslip.com/en/problems/rate-limited) | 429 | Calls came faster than a limit allows: the account's, or this key's own cap when one is set. Wait the seconds in the Retry-After header, then send again |
