URL: /api/authentication

---
title: Authentication
description: Bearer tokens — Clerk session JWTs for browsers, API keys for scripts.
---

Every authenticated endpoint accepts a bearer token in the `Authorization` header.

```http
Authorization: Bearer <token>
```

Two token types are accepted on the same header:

| Type | Prefix | Use for | Lives where |
| --- | --- | --- | --- |
| API key | `dg_live_` / `dg_test_` | Scripts, CI, server-to-server | Mint at [`/dashboard/api-keys`](https://app.domaingenius.com.au/dashboard/api-keys) |
| Session JWT | none | Browser SDK, dashboard | Issued by Clerk on sign-in |

The server picks the right verifier from the token shape. You don't pick.

## API keys

```bash
curl https://api.domaingenius.com.au/api/v1/me \
  -H "Authorization: Bearer dg_live_2k8n4j..."
```

Keys carry scopes. A key with only `domains:read` cannot create a contact. See [API keys and scopes](/api/api-keys-and-scopes).

## Session JWTs

Browser SDKs lift the JWT off the Clerk session and send it on every request. You won't usually construct these by hand. If you're building a server-side companion that acts on behalf of a signed-in user, [exchange the JWT](https://clerk.com/docs/backend-requests/handling/manual-jwt) on your backend rather than passing it to your frontend.

## Org context

Endpoints under `/api/v1/orgs/{org_oid}/...` take the organisation OID in the path. The token must belong to a member of that org.

For non-org endpoints (`/api/v1/me`, `/api/v1/domains/availability`, etc.), the token alone identifies the caller.

## What happens when auth fails

```json
{ "detail": "Not authenticated" }
```

HTTP 401 means the token is missing, malformed, expired, or revoked. HTTP 403 means the token is valid but lacks the required scope or org membership. See [Errors](/api/errors).
