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

# API Overview

> REST API overview, base URL, versioning, authentication, rate limits, and conventions.

# API Overview

The Hubify Labs REST API provides programmatic access to labs, experiments, agents, papers, tasks, and compute resources.

## Base URL

```
https://www.hubify.com/api/v1
```

All endpoints are prefixed with `/v1`. When a new API version is released, existing versions remain supported for at least 12 months.

## Authentication

Every request requires an `Authorization` header with either an API key or a Clerk JWT:

```bash theme={null}
# API key
curl https://www.hubify.com/api/v1/labs \
  -H "Authorization: Bearer hfy_key_abc123..."

# Clerk JWT
curl https://www.hubify.com/api/v1/labs \
  -H "Authorization: Bearer eyJhbGciOiJS..."
```

See [Authentication](/api/authentication) for details on obtaining credentials.

## Request Format

* **Content-Type:** `application/json` for all request bodies
* **Method conventions:** `GET` (read), `POST` (create), `PATCH` (update), `DELETE` (remove)
* **IDs:** String identifiers (e.g., `lab_abc123`, `exp_054`)

## Response Format

All responses return JSON with a consistent structure:

```json theme={null}
{
  "data": { ... },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-04-14T10:42:01Z"
  }
}
```

Error responses include a machine-readable code and human-readable message:

```json theme={null}
{
  "error": {
    "code": "not_found",
    "message": "Experiment EXP-999 does not exist.",
    "status": 404
  }
}
```

## Pagination

List endpoints support cursor-based pagination:

```bash theme={null}
GET /v1/experiments?limit=20&cursor=exp_040
```

| Parameter | Default | Description                   |
| --------- | ------- | ----------------------------- |
| `limit`   | 20      | Items per page (max 100)      |
| `cursor`  | ,       | Cursor from previous response |

Paginated responses include a `next_cursor` field:

```json theme={null}
{
  "data": [ ... ],
  "meta": {
    "next_cursor": "exp_020",
    "has_more": true
  }
}
```

## Rate Limits

| Plan | Requests/min | Requests/day |
| ---- | ------------ | ------------ |
| Free | 60           | 1,000        |
| Pro  | 300          | 50,000       |
| Team | 1,000        | 500,000      |

Rate limit headers are included in every response:

```
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 298
X-RateLimit-Reset: 1713091200
```

## Error Codes

| Code               | Status | Description                       |
| ------------------ | ------ | --------------------------------- |
| `unauthorized`     | 401    | Missing or invalid authentication |
| `forbidden`        | 403    | Insufficient permissions          |
| `not_found`        | 404    | Resource does not exist           |
| `validation_error` | 422    | Invalid request body              |
| `rate_limited`     | 429    | Too many requests                 |
| `server_error`     | 500    | Internal server error             |

## Route Catalog

Every live route in the current API. All routes require `Authorization: Bearer <token>` unless **Auth** shows `public`. The **Lab scope** column indicates whether the route operates on a specific lab (pass `labId` in body or query).

| Method                  | Path                               | Auth     | Lab scope | Status |
| ----------------------- | ---------------------------------- | -------- | --------- | ------ |
| `GET`                   | `/api/v1/status`                   | public   | no        | live   |
| `GET`                   | `/api/v1/me`                       | required | no        | live   |
| `GET`                   | `/api/v1/labs`                     | required | no        | live   |
| `GET,POST,DELETE`       | `/api/v1/auth/keys`                | required | no        | live   |
| `GET`                   | `/api/v1/activity`                 | required | yes       | live   |
| `GET`                   | `/api/v1/agents`                   | required | yes       | live   |
| `GET,POST`              | `/api/v1/backups`                  | required | yes       | live   |
| `POST`                  | `/api/v1/chats/[id]/promote`       | required | yes       | live   |
| `GET,POST`              | `/api/v1/contributions`            | required | yes       | live   |
| `GET`                   | `/api/v1/costs`                    | required | yes       | live   |
| `GET,POST`              | `/api/v1/datasets`                 | required | yes       | live   |
| `GET,POST`              | `/api/v1/experiments`              | required | yes       | live   |
| `GET,POST`              | `/api/v1/experiments/costs`        | required | yes       | live   |
| `GET,POST`              | `/api/v1/experiments/queues`       | required | yes       | live   |
| `GET,POST`              | `/api/v1/experiments/templates`    | required | yes       | live   |
| `GET`                   | `/api/v1/figures`                  | required | yes       | live   |
| `GET,POST,PATCH,DELETE` | `/api/v1/files`                    | required | yes       | live   |
| `GET,POST`              | `/api/v1/knowledge`                | required | yes       | live   |
| `GET,POST`              | `/api/v1/memory`                   | required | yes       | live   |
| `GET,POST`              | `/api/v1/papers`                   | required | yes       | live   |
| `POST`                  | `/api/v1/papers/[id]/publish-loop` | required | yes       | live   |
| `GET`                   | `/api/v1/pods`                     | required | yes       | live   |
| `POST`                  | `/api/v1/pods/[podId]/start`       | required | yes       | live   |
| `POST`                  | `/api/v1/pods/[podId]/stop`        | required | yes       | live   |
| `GET,POST`              | `/api/v1/projects`                 | required | yes       | live   |
| `GET`                   | `/api/v1/search`                   | required | yes       | live   |
| `GET,POST`              | `/api/v1/standups`                 | required | yes       | live   |
| `GET,POST`              | `/api/v1/surveys`                  | required | yes       | live   |
| `GET,POST`              | `/api/v1/sync`                     | required | yes       | live   |
| `POST`                  | `/api/v1/sync/secret`              | required | yes       | live   |
| `GET,POST`              | `/api/v1/tasks`                    | required | yes       | live   |
| `DELETE`                | `/api/v1/tasks/[taskId]`           | required | yes       | live   |
| `GET,POST`              | `/api/v1/telemetry`                | required | yes       | live   |

<Note>
  Routes marked **planned** exist in the docs but have no handler yet. Ghost routes are noted at the top of their respective reference pages.
</Note>

## SDKs

Official SDKs are available for common languages:

```bash theme={null}
# Node.js / TypeScript
npm install @hubify/sdk

# Python
pip install hubify
```

```typescript theme={null}
import { Hubify } from '@hubify/sdk';

const client = new Hubify({ apiKey: process.env.HUBIFY_API_KEY });
const labs = await client.labs.list();
```
