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

# Authentication

> Organization API keys for the Cicini Public API

# Authentication

Public API v1 uses **HTTP Bearer** authentication with an **organization API key**.

## Header

```http theme={null}
Authorization: Bearer cic_test_…
```

or

```http theme={null}
Authorization: Bearer cic_live_…
```

| Prefix      | Intended use          |
| ----------- | --------------------- |
| `cic_test_` | Development / sandbox |
| `cic_live_` | Production            |

Keys are generated server-side (`cic_test_` or `cic_live_` + 64 hex characters). Only the **hash** is stored; the full secret is shown once at creation.

## Create a key (dashboard)

1. Sign in as an org **owner** or **admin**.
2. Open **Settings → Integrations → API keys** (`/dashboard/settings/integrations/api-keys`).
3. Create a test or live key.
4. Copy the secret immediately and store it in your secret manager.

Creating or listing keys requires **API access** on the plan (`apiAccess` / `apiAccessEnabled`). Per plan-core:

| Plan                        | API access | Max API keys (catalog) |
| --------------------------- | ---------- | ---------------------- |
| Free                        | No         | 0                      |
| Starter (\$19/mo list)      | No         | 0                      |
| Professional (\$49/mo list) | Yes        | 5                      |
| Enterprise                  | Yes        | Unlimited (catalog)    |

Upgrade path in-product: `/dashboard/billing/upgrade`.

## Rules

* Send the full key **only** in the `Authorization` header.
* Never put live keys in frontend JavaScript, mobile apps you ship to end users, git, or support tickets.
* Missing / malformed header → **401** `{ "error": "Unauthorized", "message": "API key required in Authorization header" }`.
* Invalid, revoked, or expired key → **401** `{ "error": "Unauthorized", "message": "Invalid or expired API key" }`.
* Each key is scoped to **one organization**. Responses only include that org’s data. You do not pass `orgId` on public routes.

## Example

```bash theme={null}
export CICINI_API_KEY="cic_test_…"

curl -sS \
  -H "Authorization: Bearer $CICINI_API_KEY" \
  "https://cicini.com/api/public/v1/appointments?limit=5"
```

## OpenAPI security scheme

The published OpenAPI document defines `bearerAuth` (HTTP bearer, API key). Importers of `/openapi.json` will prompt for a token automatically.

## Not supported on public v1

| Mechanism                      | Status                                 |
| ------------------------------ | -------------------------------------- |
| OAuth 2.0 for third-party apps | Not public v1                          |
| NextAuth session cookies       | Web app only                           |
| SCIM bearer tokens             | Separate SCIM surface — not this guide |
| User password grants           | Not applicable                         |
