> ## Documentation Index
> Fetch the complete documentation index at: https://docs.matambaintelligence.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Keys and security

> How API keys are issued, restricted and revoked, and what we store about your customers.

## API keys

| Key     | Starts with | Works on              | Works from                                         |
| ------- | ----------- | --------------------- | -------------------------------------------------- |
| Sandbox | `mgw_test_` | The sandbox host only | Any address                                        |
| Live    | `mgw_live_` | The live host only    | Only the IP addresses and ranges registered for it |

After the prefix, a key has 43 characters generated from 32 random bytes. Send it in the `Authorization` header as `Bearer` and the key. A key sent to the wrong environment's host returns `401 unauthorized`, with a message that says so.

### How keys are issued

We issue keys. There's no API to create one. We show a new key once and store only a hash of it, so we can't show it again or recover it. If you lose a key, we issue a new one and revoke the old one. Keep keys on your servers, in a secrets manager, and never in an app or web page your customers download.

Keys don't expire, and every key can use every endpoint.

### Rotate or revoke a key

You can hold more than one key at a time. To rotate a key:

1. Ask us for a second key. We send it to you.
2. Switch your servers to the new key.
3. Tell us, and we revoke the first key.

When we revoke a key, it stops working on the next request. If a key leaks, tell us at once and we revoke it.

### Live keys and IP addresses

A live key works only from the addresses you register with it. Send us each address or range your servers send requests from. Each entry is a single address, such as `203.0.113.10`, or a range, such as `203.0.113.0/29`.

| Rule                                                                  | Why                                                                                                                                                      |
| --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| At least one entry.                                                   | A live key that works from anywhere is one leak away from trading.                                                                                       |
| IPv4 ranges no wider than `/20`, and IPv6 ranges no wider than `/56`. | A wider range covers far more of the internet than your servers.                                                                                         |
| No private, loopback, link-local, multicast or unspecified addresses. | Requests from your servers reach us from public addresses. One of these would mean something between us hides the real sender, or would let in everyone. |

We read the address from the connection itself, never from a header such as `X-Forwarded-For`. A request from an address that isn't registered returns `401 unauthorized`, the same response as an invalid key, so the response never confirms to someone holding a stolen key that it's valid. If your live requests start failing with `401`, check whether your servers' outbound addresses have changed.

## Connections

The API is served over HTTPS with TLS 1.2 or later.

Our responses carry these headers:

| Header          | Value                                                                                              |
| --------------- | -------------------------------------------------------------------------------------------------- |
| `x-request-id`  | An ID we create for the request, starting with `req_`. Log it, and include it when you contact us. |
| `Cache-Control` | `no-store`, so no cache keeps a response.                                                          |

## Your customers' data

When you apply for an account, we pass your customer's identity details to the broker and don't keep them. For an application we store only:

* its state,
* the broker's reference for it,
* the account number, once the account opens,
* a keyed hash of the application, so we can tell a retry from a different application. The key for that hash isn't stored with our data.

We never store or log a customer's name, date of birth, BVN, NIN, phone number, email address, home address, next of kin or bank details. An error names the field at fault in `param` and never repeats its value.

Balances, positions, trades and contract notes are read from the broker each time you ask, and we don't store them. We do store your orders, allocations and wallet ledger, and a record of each message we exchange with the broker about them. These carry account codes but no names. Our logs record the route a request used, not its path, so account codes in a path aren't logged.

## Webhooks

Every event we send is signed. Verify each one before you act on it. See [Webhooks](/webhooks).
