# Authentication

The v3 API is served at `https://api.cademi.com.br/api/v3`. It accepts HTTPS only and uses no cookies, sessions, or CSRF tokens. The credential, not the host, identifies the account: a credential issued for account A always operates on account A's data, whichever host you call.

## Autonomous mode

This is the common case: your integration calls the API on behalf of a system, with no person involved.

```
GET /api/v3/credentials/current
Authorization: Bearer ck_live_9f2c...
```

The secret is returned only once, when the credential is created, and no operation returns it again. Treat it like a password: the secret alone authenticates and authorizes calls. Sandbox secrets start with `ck_test_`.

## Human mode (OAuth plus credential)

When a call must be attributed to a real administrator (for example, a CLI or a third-party dashboard), issue the credential in human mode and send both values on every call:

```
GET /api/v3/users?limit=50
Authorization: Bearer <admin access token>
X-API-Key: ck_live_9f2c...
```

Both values are validated, with no fallback: a revoked, suspended, or expired credential is rejected before the access token is checked. The administrator must belong to the same account as the credential and be linked to it. Human mode does not extend the credential's policy: authorization is still determined by the credential, and the administrator is recorded as the author in the audit trail. The authorization flow, the OAuth endpoints, and token renewal are covered in [Human mode (OAuth)](https://cademi.dev/api/oauth.md).

`GET /credentials/current` tells you who you are: the credential ID, environment, mode, effective permissions and, in human mode, the `human` object with the administrator and its validity.

## Headers

| Header | Direction | Purpose |
|---|---|---|
| `Authorization: Bearer <secret>` | request | Autonomous mode. Never send it in the query string, body, or a cookie. |
| `Authorization: Bearer <access token>` plus `X-API-Key` | request | Human mode. |
| `Idempotency-Key` | request | Required on every `POST` that has side effects; accepted on `PATCH`, `PUT`, and `DELETE`. See [Asynchronous operations, batches, and idempotency](https://cademi.dev/api/operations.md). |
| `If-Match` | request | Conditional write based on the resource revision. See [Pagination, filtering, and conditional requests](https://cademi.dev/api/pagination-and-filtering.md). |
| `Accept-Language` | request | Language of `error.message` and other human-readable text. Defaults to `en-US`. |
| `Content-Type: application/json` | request | Required when the request has a body. Any other type returns `415`. The v3 API never accepts file bytes. |
| `X-Client`, `X-Client-Version`, `X-Client-Install-Id` | request | Identify your client in the audit trail. They do not grant any access. |
| `X-Request-Id` | response | Identifier of the call, the same value as `error.request_id` and the audit entry. |
| `X-Cademi-Release` | response | Contract release that served the response, for example `3.2.0`. |
| `X-Cademi-Environment` | response | `production` or `sandbox`. |
| `Retry-After` | response | Seconds to wait before retrying after a `429` (and after a `503` when the wait is known). See [Limits, quotas, and retention](https://cademi.dev/api/limits.md). |
| `Deprecation`, `Sunset` | response | The operation or field is deprecated. See [Versioning and compatibility](https://cademi.dev/api/versioning.md). |

## Authentication failures

| Code | When |
|---|---|
| `unauthenticated` | No credential was sent, its format is not recognized, or the credential does not exist. |
| `credential_revoked`, `credential_suspended`, `credential_expired` | The credential exists but is no longer valid. |
| `human_context_required` | The credential requires human mode, but only the key was sent. |
| `invalid_access_token` | The administrator's access token is not valid. |
| `ambiguous_credentials` | The call mixes both modes, or sends an ID token instead of an access token. |
| `human_mode_not_allowed`, `tenant_mismatch`, `admin_not_eligible` | The administrator and credential pair is not accepted. |
| `instance_blocked` | The account is blocked. Nothing is counted against your rate limit. |

All of these return `401`, except the three pair codes and `instance_blocked`, which return `403`. The full list is in [Errors](https://cademi.dev/api/errors.md).

## First call

1. Create a credential in your Cademí dashboard and store the secret.
2. Publish a policy with the permissions your integration needs ([Permissions and scope](https://cademi.dev/api/access-control.md)).
3. Confirm with `GET /credentials/current`, then continue with [Examples](https://cademi.dev/api/examples.md).
