# REST API reference

Source: https://docs.elnora.ai/docs/api
Last modified: 2026-09-16T13:37:22-06:00

> The Elnora core REST API — base URL, authentication, conventions, and the full resource catalog.

The Elnora **core REST API** is the programmatic surface behind the CLI, the MCP
server, and the app. Everything you can do in the dashboard, you can do over HTTP.

- **Base URL:** `https://platform.elnora.ai/api/v1`
- **Format:** JSON request and response bodies. Resource ids are UUIDs.
- **Auth:** an API key in the `X-API-Key` header (see [Authentication](https://docs.elnora.ai/docs/get-started/authentication)).

  Every endpoint has a reference page under **API → Endpoints** with its
  parameters, request/response, and a copy-paste `curl` example — generated from
  the API's OpenAPI specification, so it always matches production.

## Authentication

Send your API key on every request:

```bash
curl https://platform.elnora.ai/api/v1/tasks \
  -H "X-API-Key: $ELNORA_API_KEY"
```

You can equivalently send `Authorization: Bearer <your-key>`. Interactive clients
(including the MCP server) may use OAuth 2.1 instead. Requests act on your
**active organization**; some endpoints accept an explicit organization id to
target another org you belong to. Tasks are readable only by the account that
created them, and file endpoints return a file only when your account has access
to it — a key acts with its creator's access, so create a key under the account
whose view of the data your integration needs.

## Conventions

- **Pagination** — list endpoints take `page` and `pageSize` (max 100); message
  history uses cursor pagination (`Cursor` / `Limit`).
- **Versioning** — the API is versioned in the path (`/api/v1`).

### Errors

Errors use standard HTTP status codes with a consistent JSON body:

```json
{
  "errorCode": "NOT_FOUND",
  "messages": ["Task not found."],
  "correlationId": "b1f2…"
}
```

`errorCode` is a stable machine-readable string (e.g. `BAD_REQUEST`,
`UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `FILE_EXPIRED`, `VERSION_CONFLICT`,
`INSUFFICIENT_SCOPE`, `ORGANIZATION_ACCESS_REVOKED`,
`RATE_LIMIT_EXCEEDED`); `messages` is safe to show a user; `correlationId`
identifies the request in our logs — include it when contacting support. Common
statuses: `400` an invalid or malformed request (including validation errors),
`401` unauthenticated, `403` not permitted for your role, `404` not found,
`409` a version conflict (re-read and retry).

Two `403`s are worth handling on their own, because retrying will not help:
`INSUFFICIENT_SCOPE` means the API key may not call that endpoint (see
[Authentication](https://docs.elnora.ai/docs/get-started/authentication)), and
`ORGANIZATION_ACCESS_REVOKED` means the token's access to the organization has
ended and an interactive client needs to authorize again. Both are written before
a request reaches the endpoint, so they carry `errorCode` and `messages` but no
`correlationId`.

When you create a task or send a message that references a file which has since
been archived or expired, the `404` uses `errorCode: "FILE_EXPIRED"` and adds a
`missingFileIds` array listing exactly which ids failed, so you can re-upload
them and retry in one round-trip.

### Rate limits

The API is rate limited per client. When you exceed a limit you get
`429 Too Many Requests` with a `Retry-After` header (seconds to wait) and the
error body above with `errorCode: "RATE_LIMIT_EXCEEDED"`. Back off and retry
after the indicated delay; for bulk work, prefer batch endpoints and a modest
concurrency.

## A first request

Check connectivity and build provenance (no auth required):

```bash
curl https://platform.elnora.ai/api/v1/version
```

Create a task and send the agent a message:

```bash
# 1. Create a task
curl -X POST https://platform.elnora.ai/api/v1/tasks \
  -H "X-API-Key: $ELNORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Optimize transfection" }'

# 2. Send a message; the agent works on it asynchronously
curl -X POST https://platform.elnora.ai/api/v1/tasks/<task-uuid>/messages \
  -H "X-API-Key: $ELNORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Optimize a HEK293 transfection protocol for higher yield" }'

# 3. Read the reply — poll the task's messages until the agent responds.
#    Cursor pagination: pass ?Cursor=<nextCursor>&Limit=50 to page.
curl https://platform.elnora.ai/api/v1/tasks/<task-uuid>/messages \
  -H "X-API-Key: $ELNORA_API_KEY"

# Files you attached to the chat stay scoped to the task.
curl https://platform.elnora.ai/api/v1/tasks/<task-uuid>/attachments \
  -H "X-API-Key: $ELNORA_API_KEY"

# Files the agent produced land in your knowledge base — browse it from its roots.
curl https://platform.elnora.ai/api/v1/folders/roots \
  -H "X-API-Key: $ELNORA_API_KEY"
```

## Resources

| Resource | What it covers |
| --- | --- |
| **Account** | Your profile, email confirmation, sign-in, and account deletion. |
| **API keys** | Create, list, and revoke keys; read and set your org's key policy. |
| **Organizations** | List and switch orgs, members and roles, invitations, exports, billing status, knowledge-base auto-tidy. |
| **Invitations** | Look up and accept an invitation to join an organization. |
| **Files** | Upload, download, share, move, and version files; set a description and tags; read effective access; working copies, fork, promote. |
| **Folders** | Create, rename, move, archive, and share folders; read effective access, break inheritance, and review or clear files shared more widely than their folder. |
| **Library** | Your organization's shared collection of reusable content. |
| **Tasks & messages** | Drive the agent — create tasks, send messages, read attachments. |
| **Search** | Search across tasks, files, file content, and your knowledge base. |
| **Audit log** | Read your organization's audit trail (org admins) — including actions the agent took on your behalf, filterable by actor type. |
| **Feedback** | Submit product feedback. |
| **Version** | Build and release provenance. |

  Per-endpoint pages are listed under **API → Endpoints** in the sidebar, grouped
  by resource. They are generated from the OpenAPI spec and regenerated
  automatically whenever the API changes, so they never drift from production.
