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

# API authentication

> API authentication via Supabase JWT

Vibely uses **Supabase-issued JWTs** for API authentication. Every request to `/api/*` (except explicitly exempt paths) must include a Bearer token.

<Frame>
  <img src="https://cdn.vibely.sh/doc/v1/api-reference-auth.webp" alt="Bearer JWT or project API key" width="1200" height="675" />
</Frame>

## Getting a token

Vibely is a single-page app — auth happens client-side via Supabase Auth. The frontend manages token acquisition and refresh transparently through `@supabase/ssr`.

For API consumers (MCP clients, CI scripts, external services):

1. Sign in to Vibely at `https://vibely.sh`
2. The session token is stored in the browser
3. For programmatic access, use an MCP API key (see below)

## Bearer token

```http theme={"system"}
Authorization: Bearer <supabase-jwt>
```

```bash theme={"system"}
curl -H "Authorization: Bearer $TOKEN" https://api.vibely.sh/api/v1/vibe/projects
```

## Token lifecycle

* Tokens are **short-lived** (1 hour by default)
* The frontend client refreshes automatically on 401
* If calling the API directly, handle 401 by re-authenticating

## Auth-exempt paths

These paths skip Bearer validation — each authenticates itself by some other
means (its own signature check, an `x-api-key`, or a provider callback secret):

* `GET /api/v1/health`, `GET /api/v1/vibe/models`, `GET /api/v1/vibe/providers`
* `GET /api/v1/billing/plans`, `GET /api/v1/billing/config`, `POST /api/v1/billing/webhook`
* `POST /api/v1/git/oauth/callback`, `/api/v1/supabase/oauth/callback`, `/api/v1/stripe/oauth/callback`
* `/api/v1/mcp/info`, `/api/v1/mcp/catalog`, `/api/v1/mcp/oauth/begin`, `/api/v1/mcp/oauth/callback`
* `/api/v1/ai/*` — the AI gateway, which does its own `x-api-key` check
* `POST /api/v1/internal/analytics/collect` and the other `/api/v1/internal/*` webhooks
* `/api/v1/public/*` and `/api/v1/gw/*`

The list is exhaustive and lives in one place: `isAuthExempt()` in
`src/middleware/auth-exempt.ts`. Matching is exact or by an anchored pattern —
never a loose substring, so a path that merely *contains* an exempt one
(`.../files/git/oauth/callback`) still authenticates.

## AI gateway API keys

The `/api/v1/ai/*` gateway — what a generated app calls for chat, images, video,
speech, and embeddings — authenticates with a per-project API key instead of a
user JWT:

```http theme={"system"}
x-api-key: <project-api-key>
```

Keys are minted per project, hashed at rest, and revocable; the key identifies
the project whose credit balance the call is billed to. A missing header is a
`401 x-api-key header is required` before any model call is made.

## Error responses

| Status | Code | When |
| - | - | - |
| 401 | `AUTH_REQUIRED` | No Bearer header or empty token |
| 401 | `TOKEN_INVALID` | Token is malformed, expired, or fails validation |
| 403 | `ACCESS_DENIED` | Valid token but caller lacks permission for this resource |

See [Error Format](/api-reference/errors) for the full response shape.


## Related topics

- [API Overview](/api-reference/overview.md)
- [Connector authentication and credentials](/integrations/connectors/auth.md)
- [Connect tools, services, and APIs](/integrations/connectors/overview.md)
- [Connect a custom MCP server](/integrations/connectors/custom-mcp.md)
- [Error Format](/api-reference/errors.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.