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

# Authentication

> How to authenticate with the Metabind API

All Metabind API requests require authentication. The platform supports two authentication methods depending on your use case.

## Route structure

The Metabind API uses two route prefixes that determine which authentication method to use:

| Route prefix | Authentication        | Access level | Use case                      |
| ------------ | --------------------- | ------------ | ----------------------------- |
| `/app/v1/`   | JWT Bearer token      | Full CRUD    | App Studio, admin operations  |
| `/api/v1/`   | API key (`x-api-key`) | Read-only    | Client apps, content delivery |

**All endpoints** are available via `/app/v1/` with JWT authentication. **Some endpoints** are also available via `/api/v1/` with API key authentication for read-only access to published content.

## Bearer token authentication

For administrative operations and full API access, use JWT bearer tokens with the Admin API (`/app/v1/` routes).

### Obtaining a JWT token

JWT tokens are obtained by signing into [App Studio](https://metabind.ai). After authentication, your session provides the JWT tokens used for API requests.

For programmatic access to admin operations:

1. Sign into App Studio.
2. Use browser developer tools to inspect the `Authorization` header in API requests.
3. Copy the bearer token for use in your scripts or tools.

<Note>
  JWT tokens expire periodically. For long-running integrations that need admin access, create a dedicated user with an appropriately scoped role and refresh its JWT through the standard sign-in flow. There is no separate "service account" entity today — the convention is to provision a user that exists for automation only.
</Note>

### Using bearer tokens

Include the JWT in the `Authorization` header:

```javascript theme={null}
headers: {
  'Authorization': 'Bearer YOUR_JWT',
  'Content-Type': 'application/json'
}
```

Example request:

```bash theme={null}
curl -X GET "https://api.metabind.ai/app/v1/organizations/org123/projects/proj456/content" \
  -H "Authorization: Bearer YOUR_JWT"
```

## API key authentication

For client applications consuming published content, use API key authentication with the Client API (`/api/v1/` routes). This is the recommended approach for mobile apps, web frontends, and other client-side integrations.

<Note>
  When building client applications (iOS, Android, React, web), use the `/api/v1/` routes with API keys. Reserve `/app/v1/` routes for admin tools and integrations that require full access.
</Note>

### REST client API

Include the API key in the `x-api-key` header:

```javascript theme={null}
headers: {
  'x-api-key': 'YOUR_API_KEY',
  'Content-Type': 'application/json'
}
```

### GraphQL API

For the GraphQL API, use the same `x-api-key` header:

```javascript theme={null}
headers: {
  'x-api-key': 'YOUR_API_KEY',
  'Content-Type': 'application/json'
}
```

### WebSocket subscriptions

For real-time subscriptions, include the API key in the connection parameters:

```javascript theme={null}
connectionParams: {
  headers: {
    'x-api-key': 'YOUR_API_KEY'
  }
}
```

## Obtaining API keys

API keys are created and managed in App Studio:

1. Navigate to your project settings.
2. Go to the **API Keys** section.
3. Click **Create API Key**.
4. Provide a name and optional description.
5. Copy the generated key — it won't be shown again.

<Warning>
  API keys are displayed only once when created. Store them securely. If you lose an API key, you'll need to create a new one.
</Warning>

## API key access

API keys provide **read-only access** to published content within their project scope. They cannot:

* Create, update, or delete resources
* Access draft content
* Access administrative functions

For administrative operations, use bearer token authentication with appropriate user permissions.

## Client API endpoints

The following endpoints are available via `/api/v1/` with API key authentication. All return **published content only**.

For practical code examples using these endpoints, see [Using API keys](/rest/api-keys/usage).

### Content discovery

<CardGroup cols={1}>
  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/saved-searches`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/saved-searches/{savedSearchId}`
  </Card>

  <Card>
    **POST** `/api/v1/organizations/{organizationId}/projects/{projectId}/saved-searches/{savedSearchId}/execute`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/tags`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/tags/{tagId}`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/content-types`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/content-types/{contentTypeId}`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/content-types/{contentTypeId}/versions`
  </Card>
</CardGroup>

### Content access

<CardGroup cols={1}>
  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/components`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/components/{componentId}`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/packages`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/packages/{version}/resolved`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/content`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/content/{contentId}/resolved`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/assets`
  </Card>
</CardGroup>

### Real-time updates

<CardGroup cols={1}>
  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/events`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/{resourceType}/events`
  </Card>

  <Card>
    **GET** `/api/v1/organizations/{organizationId}/projects/{projectId}/{resourceType}/{resourceId}/events`
  </Card>
</CardGroup>

## Security best practices

<AccordionGroup>
  <Accordion title="Never expose API keys in client-side code">
    API keys should be kept on the server side. For mobile apps, use a backend proxy or the GraphQL API with appropriate rate limiting.
  </Accordion>

  <Accordion title="Use environment-specific keys">
    Create separate API keys for development, staging, and production environments.
  </Accordion>

  <Accordion title="Rotate keys regularly">
    Periodically revoke old API keys and create new ones, especially if you suspect a key may have been compromised.
  </Accordion>

  <Accordion title="Revoke unused keys">
    Delete API keys that are no longer in use to reduce your attack surface.
  </Accordion>
</AccordionGroup>
