---
title: "Authentication"
description: "How to authenticate against the Minima APIs, and how to make your first request"
---

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

# Authentication

Every Minima API request is authenticated with an API key sent in the `x-api-key` header. There are no other authentication methods, and there is no OAuth flow.

```bash
curl https://api.minima.ltd/api/v1/me \
  -H "x-api-key: priv_your_key_here"
```

That endpoint is the fastest way to check a key works. It needs nothing but the key itself, and it answers with what the key can do:

```json
{
  "key": { "id": "key_...", "name": "Production", "type": "admin" },
  "role": "admin",
  "organizationId": "org_...",
  "siteId": null,
  "siteScope": null,
  "permissions": ["entities:read", "entities:write", "..."]
}
```

Use it when you are setting up. It is also the only route that resolves entirely from the key — every other organization route needs your organization ID in the path, so `/me` is how you discover which organization a key belongs to.

## Two APIs, one host

Everything lives under `https://api.minima.ltd/api/v1`. Below that base URL there are two separate APIs, and which one you want depends on whether you are building a front end or an integration.

| | Admin API | Public API |
|---|---|---|
| Path | `/{orgId}/…` | `/public/sites/{siteId}/…` |
| Key prefix | `priv_` | `pub_` |
| Scope | Your whole organization | One site |
| Methods | Read and write | Read only |
| Content | Drafts and published | Published only |
| Safe in a browser | No | Yes |

The Public API is the one you build a website against. Its routes live under `/public/sites/{siteId}/`, it returns only published content, and it is CORS-enabled for `GET` so you can call it from the browser.

The Admin API is everything else — creating and updating content, managing sites, publishing. Its keys can do destructive things, so they belong on a server.

> **Caution**
>
> A `priv_` key can perform any action on your organization, including deleting content. Never ship one to a browser, a mobile app, or a public repository.

See [API keys](/developers/api-keys) for how the two key types differ and how to create one.

## Your first Public API request

A Public API key is bound to a single site, so every request names that site in the path:

```bash
curl https://api.minima.ltd/api/v1/public/sites/site_abc123/articles \
  -H "x-api-key: pub_your_key_here"
```

The site in the URL must be the site the key is scoped to. Calling a different site with the same key returns `403`, not an empty result.

Because these responses carry no credentials, the Public API sends permissive CORS headers for `GET` and `OPTIONS`, and `x-api-key` is an allowed request header. Fetching directly from the browser works:

```js
const response = await fetch(
  "https://api.minima.ltd/api/v1/public/sites/site_abc123/articles",
  { headers: { "x-api-key": "pub_your_key_here" } },
)
const { data } = await response.json()
```

## Your first Admin API request

Admin routes are scoped to your organization, which appears in the path:

```bash
curl https://api.minima.ltd/api/v1/org_abc123/entities \
  -H "x-api-key: priv_your_key_here"
```

Get your organization ID from `/me`, or from the URL in the Minima dashboard.

## When authentication fails

Failures come back as JSON with a matching HTTP status.

```json
{
  "url": "/api/v1/me",
  "status": 401,
  "statusCode": 401,
  "statusMessage": "Invalid API key",
  "message": "Invalid API key",
  "error": true
}
```

| Status | Message | What happened |
|---|---|---|
| `401` | `Missing API key` | No `x-api-key` header was sent |
| `401` | `Invalid API key` | The key is not recognised, or it has been revoked |
| `403` | `Unauthorized` | The key is valid but does not cover this organization, site, or action |

A revoked key and a key that never existed both return `Invalid API key`. That is deliberate — telling you which one it was would confirm a guess for anyone probing keys. If a key stops working unexpectedly, check whether it was revoked in Settings rather than reading anything into the message.

Source: https://docs.minima.ltd/developers/authentication/index.mdx
