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

# Developer API

> Programmatically manage your CMS collections and content items

The Relixir Developer API allows you to programmatically access and manage your CMS content. Use it to integrate Relixir with your existing workflows, build custom integrations, or automate content management.

## Base URL

```
https://api.relixir.ai
```

## Authentication

All API requests require authentication using an API key. Include your API key in the `Authorization` header:

```bash theme={null}
Authorization: Bearer rlx_live_your_api_key_here
```

### Creating an API Key

1. Go to **Settings** → **Developer API** in your Relixir dashboard
2. Click **Create API key**
3. Give your key a descriptive name (e.g., "Production API Key")
4. Copy the key immediately - it will only be shown once

<Warning>
  Keep your API keys secure. Never expose them in client-side code or commit them to version control.
</Warning>

## Interactive Documentation

Full interactive API documentation with request/response examples is available at:

<Card title="API Reference" icon="book" href="https://api.relixir.ai/docs">
  Explore the full API with Swagger UI
</Card>

## Endpoints

### Collections

<AccordionGroup>
  <Accordion title="List Collections" icon="list">
    Returns all internal (Relixir-owned) CMS collections for your organization.

    **Request**

    ```bash theme={null}
    GET /v1/collections
    ```

    **Query Parameters**

    | Parameter | Type    | Default | Description                           |
    | --------- | ------- | ------- | ------------------------------------- |
    | `limit`   | integer | 100     | Maximum number of collections (1-500) |
    | `offset`  | integer | 0       | Number of collections to skip         |

    **Example**

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X GET "https://api.relixir.ai/v1/collections" \
        -H "Authorization: Bearer rlx_live_your_api_key"
      ```

      ```python Python theme={null}
      import requests

      response = requests.get(
          "https://api.relixir.ai/v1/collections",
          headers={"Authorization": "Bearer rlx_live_your_api_key"}
      )
      collections = response.json()
      ```

      ```javascript Node.js theme={null}
      const response = await fetch("https://api.relixir.ai/v1/collections", {
        headers: { Authorization: "Bearer rlx_live_your_api_key" }
      });
      const collections = await response.json();
      ```
    </CodeGroup>

    **Response**

    ```json theme={null}
    {
      "collections": [
        {
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "created_at": "2024-01-15T10:30:00Z",
          "updated_at": "2024-01-15T10:30:00Z",
          "name": "Blog Posts",
          "slug": "blog",
          "settings": {}
        }
      ],
      "total": 1
    }
    ```
  </Accordion>

  <Accordion title="Get Collection" icon="folder">
    Get details of a specific collection by ID.

    **Request**

    ```bash theme={null}
    GET /v1/collections/{collection_id}
    ```

    **Example**

    ```bash theme={null}
    curl -X GET "https://api.relixir.ai/v1/collections/550e8400-e29b-41d4-a716-446655440000" \
      -H "Authorization: Bearer rlx_live_your_api_key"
    ```
  </Accordion>
</AccordionGroup>

### Content Items

<AccordionGroup>
  <Accordion title="List Items" icon="list">
    Returns content items with optional filters.

    **Request**

    ```bash theme={null}
    GET /v1/items
    ```

    **Query Parameters**

    | Parameter       | Type    | Description                                        |
    | --------------- | ------- | -------------------------------------------------- |
    | `collection_id` | UUID    | Filter by collection                               |
    | `status`        | string  | Filter by status: `draft`, `published`, `archived` |
    | `limit`         | integer | Maximum items to return (1-500, default: 100)      |
    | `offset`        | integer | Number of items to skip                            |

    **Example**

    ```bash theme={null}
    curl -X GET "https://api.relixir.ai/v1/items?collection_id=550e8400-e29b-41d4-a716-446655440000&status=published" \
      -H "Authorization: Bearer rlx_live_your_api_key"
    ```

    **Response**

    ```json theme={null}
    {
      "items": [
        {
          "id": "660e8400-e29b-41d4-a716-446655440001",
          "created_at": "2024-01-15T10:30:00Z",
          "updated_at": "2024-01-15T10:30:00Z",
          "collection_id": "550e8400-e29b-41d4-a716-446655440000",
          "status": "published",
          "slug": "hello-world",
          "title": "Hello World",
          "body": "<p>Welcome to my blog!</p>",
          "meta_description": "An introduction post",
          "thumbnail_url": null,
          "current_revision_id": null
        }
      ],
      "total": 1,
      "limit": 100,
      "offset": 0
    }
    ```
  </Accordion>

  <Accordion title="Get Item" icon="file">
    Get a specific content item by ID.

    **Request**

    ```bash theme={null}
    GET /v1/items/{item_id}
    ```

    **Example**

    ```bash theme={null}
    curl -X GET "https://api.relixir.ai/v1/items/660e8400-e29b-41d4-a716-446655440001" \
      -H "Authorization: Bearer rlx_live_your_api_key"
    ```

    **Response**

    ```json theme={null}
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z",
      "collection_id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "published",
      "slug": "hello-world",
      "title": "Hello World",
      "body": "<p>Welcome to my blog!</p>",
      "meta_description": "An introduction post",
      "thumbnail_url": null,
      "current_revision_id": "770e8400-e29b-41d4-a716-446655440003"
    }
    ```
  </Accordion>

  <Accordion title="Get Item by Slug" icon="link">
    Get a content item by its slug. This is useful when you know the URL slug but not the item ID. Searches across all collections by default, or within a specific collection if `collection_id` is provided.

    **Request**

    ```bash theme={null}
    GET /v1/items/by-slug/{slug}
    ```

    **Path Parameters**

    | Parameter | Type   | Description              |
    | --------- | ------ | ------------------------ |
    | `slug`    | string | The URL slug of the item |

    **Query Parameters**

    | Parameter       | Type | Description                               |
    | --------------- | ---- | ----------------------------------------- |
    | `collection_id` | UUID | Optional. Filter to a specific collection |

    **Example**

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X GET "https://api.relixir.ai/v1/items/by-slug/hello-world" \
        -H "Authorization: Bearer rlx_live_your_api_key"
      ```

      ```python Python theme={null}
      import requests

      response = requests.get(
          "https://api.relixir.ai/v1/items/by-slug/hello-world",
          headers={"Authorization": "Bearer rlx_live_your_api_key"}
      )
      item = response.json()
      ```

      ```javascript Node.js theme={null}
      const response = await fetch(
        "https://api.relixir.ai/v1/items/by-slug/hello-world",
        { headers: { Authorization: "Bearer rlx_live_your_api_key" } }
      );
      const item = await response.json();
      ```
    </CodeGroup>

    **Response**

    ```json theme={null}
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z",
      "collection_id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "published",
      "slug": "hello-world",
      "title": "Hello World",
      "body": "<p>Welcome to my blog!</p>",
      "meta_description": "An introduction post",
      "thumbnail_url": null,
      "current_revision_id": "770e8400-e29b-41d4-a716-446655440003"
    }
    ```
  </Accordion>

  <Accordion title="Create Item" icon="plus">
    Create a new content item in a collection.

    **Request**

    ```bash theme={null}
    POST /v1/items
    ```

    **Request Body**

    | Field                 | Type    | Required | Description                             |
    | --------------------- | ------- | -------- | --------------------------------------- |
    | `collection_id`       | UUID    | Yes      | Collection to add the item to           |
    | `slug`                | string  | Yes      | URL slug (must be unique in collection) |
    | `title`               | string  | No       | Item title                              |
    | `body`                | string  | No       | Main content (HTML or Markdown)         |
    | `meta_description`    | string  | No       | SEO meta description                    |
    | `thumbnail_url`       | string  | No       | Featured image URL                      |
    | `publish_immediately` | boolean | No       | If true, publish after creation         |

    **Example**

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST "https://api.relixir.ai/v1/items" \
        -H "Authorization: Bearer rlx_live_your_api_key" \
        -H "Content-Type: application/json" \
        -d '{
          "collection_id": "550e8400-e29b-41d4-a716-446655440000",
          "slug": "my-new-post",
          "title": "My New Post",
          "body": "<p>This is the content of my post.</p>",
          "meta_description": "A great new post about...",
          "publish_immediately": true
        }'
      ```

      ```python Python theme={null}
      import requests

      response = requests.post(
          "https://api.relixir.ai/v1/items",
          headers={
              "Authorization": "Bearer rlx_live_your_api_key",
              "Content-Type": "application/json"
          },
          json={
              "collection_id": "550e8400-e29b-41d4-a716-446655440000",
              "slug": "my-new-post",
              "title": "My New Post",
              "body": "<p>This is the content of my post.</p>",
              "publish_immediately": True
          }
      )
      item = response.json()
      ```

      ```javascript Node.js theme={null}
      const response = await fetch("https://api.relixir.ai/v1/items", {
        method: "POST",
        headers: {
          Authorization: "Bearer rlx_live_your_api_key",
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          collection_id: "550e8400-e29b-41d4-a716-446655440000",
          slug: "my-new-post",
          title: "My New Post",
          body: "<p>This is the content of my post.</p>",
          publish_immediately: true
        })
      });
      const item = await response.json();
      ```
    </CodeGroup>

    **Response** (201 Created)

    ```json theme={null}
    {
      "id": "770e8400-e29b-41d4-a716-446655440002",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z",
      "collection_id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "published",
      "slug": "my-new-post",
      "title": "My New Post",
      "body": "<p>This is the content of my post.</p>",
      "meta_description": "A great new post about...",
      "thumbnail_url": null,
      "current_revision_id": "880e8400-e29b-41d4-a716-446655440003"
    }
    ```
  </Accordion>

  <Accordion title="Update Item" icon="pen">
    Update an existing content item.

    **Request**

    ```bash theme={null}
    PATCH /v1/items/{item_id}
    ```

    **Request Body**

    All fields are optional. Only include fields you want to update.

    | Field              | Type   | Description        |
    | ------------------ | ------ | ------------------ |
    | `slug`             | string | URL slug           |
    | `title`            | string | Item title         |
    | `body`             | string | Main content       |
    | `meta_description` | string | SEO description    |
    | `thumbnail_url`    | string | Featured image URL |

    **Example**

    ```bash theme={null}
    curl -X PATCH "https://api.relixir.ai/v1/items/770e8400-e29b-41d4-a716-446655440002" \
      -H "Authorization: Bearer rlx_live_your_api_key" \
      -H "Content-Type: application/json" \
      -d '{"title": "Updated Title"}'
    ```
  </Accordion>

  <Accordion title="Delete Item" icon="trash">
    Delete a content item and all its revisions.

    **Request**

    ```bash theme={null}
    DELETE /v1/items/{item_id}
    ```

    **Example**

    ```bash theme={null}
    curl -X DELETE "https://api.relixir.ai/v1/items/770e8400-e29b-41d4-a716-446655440002" \
      -H "Authorization: Bearer rlx_live_your_api_key"
    ```

    **Response**: 204 No Content
  </Accordion>

  <Accordion title="Publish Item" icon="rocket">
    Publish a content item, creating a new revision.

    **Request**

    ```bash theme={null}
    POST /v1/items/{item_id}/publish
    ```

    **Example**

    ```bash theme={null}
    curl -X POST "https://api.relixir.ai/v1/items/770e8400-e29b-41d4-a716-446655440002/publish" \
      -H "Authorization: Bearer rlx_live_your_api_key"
    ```

    **Response**

    ```json theme={null}
    {
      "success": true,
      "message": "Content item published successfully",
      "revision_id": "990e8400-e29b-41d4-a716-446655440004",
      "revision_number": 2,
      "published_at": "2024-01-15T12:00:00Z"
    }
    ```
  </Accordion>
</AccordionGroup>

## Error Handling

The API uses standard HTTP status codes:

| Status | Description                                |
| ------ | ------------------------------------------ |
| `200`  | Success                                    |
| `201`  | Created                                    |
| `204`  | No Content (successful deletion)           |
| `400`  | Bad Request - Invalid parameters           |
| `401`  | Unauthorized - Invalid or missing API key  |
| `403`  | Forbidden - API key missing required scope |
| `404`  | Not Found - Resource doesn't exist         |
| `409`  | Conflict - e.g., duplicate slug            |
| `500`  | Server Error                               |

**Error Response Format**

```json theme={null}
{
  "detail": "Error message describing what went wrong"
}
```

## Rate Limits

* **1000 requests per minute** per API key
* **100 requests per second** burst limit

If you exceed the rate limit, you'll receive a `429 Too Many Requests` response.

## API Key Scopes

API keys have the following scopes by default:

| Scope              | Description                               |
| ------------------ | ----------------------------------------- |
| `collections:read` | Read collection information               |
| `items:read`       | Read content items                        |
| `items:write`      | Create, update, delete, and publish items |

<Note>
  Currently, all scopes are granted by default when creating an API key. Granular scope management will be available in a future update.
</Note>
