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

# Authentication

> Authenticate every request with your secret API key.

The merchant API uses **bearer token authentication**. Send your
secret key in the `Authorization` header on every request:

```http theme={null}
Authorization: Bearer sk.VCvr.1MsEBjzxlrfJdomgQlVgSlbZzFMjyQXCjnxayf6JnP6EsQEUcRgFPimPbtsP9nokwwpWmOeoweezF0Ja
```

```bash theme={null}
export KWUGWO_SECRET_KEY=sk.VCvr.1MsEBjzxlrfJdomgQlVgSlbZzFMjyQXCjnxayf6JnP6EsQEUcRgFPimPbtsP9nokwwpWmOeoweezF0Ja

curl https://api.kwugwo.africa/v1/ugwo \
  -H "Authorization: Bearer $KWUGWO_SECRET_KEY"
```

## Where to get your key

Sign in to the dashboard, open the workspace you want to integrate,
and generate a key from the **API Keys** screen. Each workspace has
one active secret key at a time; regenerating rotates the value and
invalidates the previous one immediately.

## Environments

Keys are **scoped to a single [environment](/introduction#environments)**.
The same physical workspace exists separately in sandbox and live,
each with its own keys:

| Environment | Base URL                            | Key prefix                                                                |
| ----------- | ----------------------------------- | ------------------------------------------------------------------------- |
| Sandbox     | `https://sandbox-api.kwugwo.africa` | Issued from the sandbox dashboard; use against the sandbox base URL only. |
| Live        | `https://api.kwugwo.africa`         | Issued from the live dashboard; use against the live base URL only.       |

A sandbox key sent to `api.kwugwo.africa` (or a live key sent to
`sandbox-api.kwugwo.africa`) returns `401 Unauthorized`. There is
no shared key tier.

## Two key types

Each workspace exposes two keys with different scopes:

| Key            | Prefix | Used by                                                              | Scope                                                           |
| -------------- | ------ | -------------------------------------------------------------------- | --------------------------------------------------------------- |
| **Secret key** | `sk.…` | Your backend                                                         | Full read/write on `/v1/*`. **Never expose this to a browser.** |
| **Public key** | `pk.…` | Your customer's browser (e.g. the [checkout embed](/checkout-embed)) | Read an ugwo and post charges to it from a hosted checkout.     |

Sample values look like:

```
sk.VCvr.1MsEBjzxlrfJdomgQlVgSlbZzFMjyQXCjnxayf6JnP6EsQEUcRgFPimPbtsP9nokwwpWmOeoweezF0Ja
pk.VCvr.iemkSYEKZlpPqUEoeHLqEmvbHPln4JnyNBehFnATM3GzpcMILEUjNPJSpyMuYc13JiByfYohiCPPlwnu
```

The 4-character segment after the prefix matches the [workspace
segment in your resource IDs](/ids-and-prefixes).

This reference covers the **secret-key API** at `/v1/*`. The public
key is used by the Kwugwo hosted checkout and embedded widget; you do
not need to call those endpoints yourself.

## Errors

| Status             | Meaning                                                                |
| ------------------ | ---------------------------------------------------------------------- |
| `401 Unauthorized` | Missing or malformed `Authorization` header, or the key is not active. |
| `403 Forbidden`    | The key is valid but does not have access to the resource.             |
| `404 Not Found`    | The resource does not exist on the workspace that owns this key.       |

If you regenerate a key, requests with the old value start failing
with `401` immediately; there is no grace period.

## Keep secrets secret

* Store the key in an environment variable or secrets manager, never
  in source control.
* Use the sandbox key while you build; only swap in the live key
  when you're ready to take real money.
* Rotate at the first sign of compromise. Regeneration takes effect
  instantly.
