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

> ## Agent Instructions
> Search and list return handles, provenance, and coverage. Fetch a body only with GET /v1/notes/{note} (line slice) or /raw.
> Read coverage before treating a result set as complete. Zero hits with coverage is a valid answer.
> Follow error hint. Writes need an Idempotency-Key header and agent_id.
> The user creates personal access tokens in web Settings → Access tokens. Read is included; authenticated note mutations require notes.write. Supplying agent_id does not grant permission.
> Reuse an Idempotency-Key only for an identical retry. After VERSION_MOVED, re-read and submit the changed operation with a new key.
> Local MCP is read-only. Authenticated Cloud MCP adds write_note and edit_note only with notes.write and connected write storage; open local mode skips the permission check. Inspect tools/list before calling conditional tools.
> A queued write has not changed the note. Record pending_id. Authenticated GET /v1/writes/{id} also requires notes.review; write-only tokens must hand the ID to a reviewer.
> Leave approval to a human. Agents must not approve their own proposals or request review permission merely to finish a task. The API permits review-scoped personal tokens; this is a workflow rule.
> Cloud paths never return private/ notes. Coverage names the exclusion.
> Production origin is https://api.elanotes.com. baseUrl has no /v1 suffix.

# Access tokens

> Create and revoke personal access tokens in web Settings, choose agent permissions, and connect over Cloud MCP or HTTP.

Personal access tokens are available in the hosted Ela web app. They bind requests to your vault and work with [Cloud MCP](/mcp-cloud), HTTP, the [CLI](/cli), and the workspace [SDKs](/sdk-ts).

## Create a token

1. Sign in to [Ela](https://elanotes.com/home) and open **Settings → Access tokens**.
2. Enter a descriptive **Token name**, such as `Research assistant`.
3. Leave both checkboxes off for retrieval only. Select **Write notes** if the integration must submit note mutations.
4. Reserve **Review agent writes** for a reviewer-controlled integration. An agent submitting proposals does not need this permission.
5. Click **Create token**.
6. Copy the secret immediately, or click **Copy config** to copy the Cloud MCP configuration shown beside it.
7. When you no longer need the token, click **Revoke** on its row and confirm. Clients using it will stop working.

The secret is shown only when created. Subsequent token listings never include it. If you lose it, revoke the old token and create a replacement.

The section is hidden in local mode without authentication. Desktop and iOS do not yet offer token-management UI; create tokens on the web.

## Permissions

| Capability | Behavior |
| - | - |
| Read, included on every token | Retrieve notes and use Cloud MCP retrieval tools. There is no separate read permission to select. |
| `notes.write` — **Write notes** | Submit authenticated note mutations. Cloud MCP exposes `write_note` and `edit_note` when write storage is also available. |
| `notes.review` — **Review agent writes** | Inspect write queues and receipts, approve or reject proposals, and access reviewer-protected operations such as write settings and revision rollback. |
| Signed-in session | Create, list, and revoke personal access tokens. A personal token cannot manage tokens. |

Your session can grant only permissions it already holds. A token with `notes.review` does not automatically have `notes.write`, or vice versa. These checks apply through HTTP, SDKs, CLI, and Cloud MCP.

Authenticated note mutations without `notes.write` return `403` [PERMISSION\_MISSING](/api/errors#permission_missing). Supplying `agent_id` does not grant permission. Read-only static bearers also remain read-only.

Cloud MCP retrieval tools are available to valid read-only tokens. Write tools appear only with `notes.write` and configured write storage; inspect `tools/list` before calling them. Open local mode skips the permission check. [Local MCP](/mcp-local) is always read-only.

## Call HTTP with your token

Store the copied token in `ELA_API_TOKEN` in your environment. The examples below assume it is already set; keep the secret out of committed files and shared command output.

Search requires only read access:

```bash theme={null}
curl -sS --fail-with-body \
  -H "Authorization: Bearer $ELA_API_TOKEN" \
  "https://api.elanotes.com/v1/search?q=Paddle"
```

Creating a note requires `notes.write`. Generate a fresh key for this operation; retain it and reuse it only when retrying this exact request:

```bash theme={null}
ELA_WRITE_KEY=$(uuidgen)
curl -sS --fail-with-body -X POST https://api.elanotes.com/v1/notes \
  -H "Authorization: Bearer $ELA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $ELA_WRITE_KEY" \
  -d '{"path":"agents/token-demo.md","content":"# Token demo\n","agent_id":"token-demo"}'
```

Token writes are attributed to `pat:<prefix>`, regardless of the submitted `agent_id`. They follow agent write policy, idempotency, budget, and review rather than applying as the signed-in user.

Check `status` before reading applied-only fields. An illustrative queued HTTP receipt is:

```json theme={null}
{
  "status": "queued",
  "pending_id": "3f2c1a00-0000-4000-8000-000000000012",
  "slug": "token-demo"
}
```

`queued` means the note has not changed. Record and report `pending_id`. In authenticated mode, even `GET /v1/writes/{id}` requires `notes.review`. With a write-only token, hand the ID to a reviewer; receipt polling will return `403 PERMISSION_MISSING`. With review permission, inspect the receipt and report its state. Agents must not approve their own proposals or request additional review permission just to finish a task.

An illustrative applied HTTP receipt is:

```json theme={null}
{
  "status": "applied",
  "pending_id": "3f2c1a00-0000-4000-8000-000000000010",
  "slug": "token-demo",
  "note_id": "3f2c1a00-0000-4000-8000-000000000011",
  "version_id": "3f2c1a00-0000-4000-8000-000000000002",
  "content_hash": "abc12300abc12300abc12300abc12300abc12300abc12300abc12300abc12300",
  "committed_seq": 121,
  "unchanged": false,
  "note": {
    "slug": "token-demo",
    "note_id": "3f2c1a00-0000-4000-8000-000000000011",
    "version_id": "3f2c1a00-0000-4000-8000-000000000002",
    "content_hash": "abc12300abc12300abc12300abc12300abc12300abc12300abc12300abc12300",
    "title": "Token demo",
    "observed_at": null,
    "status": "active",
    "visibility": "default"
  }
}
```

`applied` means the operation completed. `unchanged: true` means it did not create a new version. Use `committed_seq` as `min_seq` on a subsequent search when you need read-your-writes behavior.

Cloud MCP receipts differ: a queued result includes `status` and `pending_id`, without the HTTP `slug`; an applied result includes version and sequence fields, without the embedded HTTP `note`. See [MCP tools](/mcp-tools).

The API accepts review-scoped personal tokens for approval and rejection. Leaving approval to a human is the agent workflow rule, not a restriction to a human-only credential type.

## Limits and token management

* At most 25 unrevoked, unexpired tokens can exist for a subject in a vault. Revoke unused tokens before creating more.
* The API accepts an optional future `expires_at`. Settings currently has no expiry control; omitting expiry creates a token without a scheduled expiry.
* Personal tokens cannot mutate device replicas (`/v1/sync/ops`, `/v1/sync/checkpoint`, or `/v1/sync/e2ee`) or rename/delete folders. Those operations require a suitable signed-in session. Folder creation remains available with `notes.write`.

Token-management endpoints require a signed-in session, even if a personal token has both permissions:

| Operation | API reference |
| - | - |
| `POST /v1/access-tokens` | [Create a personal access token](/api-reference/identity/create-a-personal-access-token) — `name`, optional `permissions`, and optional `expires_at`; the secret is returned once. |
| `GET /v1/access-tokens` | [List personal access tokens](/api-reference/identity/list-personal-access-tokens) — metadata for the current subject and vault, without secrets. |
| `DELETE /v1/access-tokens/{id}` | [Revoke a personal access token](/api-reference/identity/revoke-a-personal-access-token) — invalidates the selected token. |

## Troubleshooting

| Result | Next action |
| - | - |
| `401 AUTH_MISSING` | Set `ELA_API_TOKEN` and send it as a bearer. |
| `401 AUTH_INVALID` | For a revoked, expired, or invalid personal token, have the user create a replacement in Settings. Personal tokens are not refreshed through OAuth. |
| `403 PERMISSION_MISSING` | Read the missing permission in the `WWW-Authenticate` scope. Use an appropriately granted credential; repeating the request will not grant permission. For queued receipts, hand the ID to a reviewer if the agent lacks `notes.review`. |
| Write tools absent from Cloud MCP | Inspect `tools/list`; check `notes.write` and write-storage availability. A successful read-only connection is valid. |
| `403 CREDENTIAL_FORBIDDEN` | Use a signed-in session for the restricted operation. Adding permissions to a personal token does not allow replica mutation or folder rename/delete. |
| `404 ACCESS_TOKEN_NOT_FOUND` | List tokens using the signed-in session and select an ID belonging to that subject and vault. |

Full reason codes: [Errors](/api/errors). Version-safe edits and retries: [Agents](/agents).


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