vault_id in the API) is what the token is bound to. Search returns structured handles with provenance. Coverage on every response says what was searched and what was left out.
How to connect
Tool arguments: MCP tools. Local MCP cannot write. Authenticated cloud MCP exposes
write_note and edit_note only with notes.write and available write storage. Inspect tools/list before calling conditional tools; a valid read-only token can connect without them. Open local mode bypasses the permission check. Review stays on HTTP.
Production origin: https://api.elanotes.com (/v1 and /mcp). Have the user create a personal access token in web Settings → Access tokens and provide it through ELA_API_TOKEN. Read is included; authenticated note mutations require notes.write. Supplying agent_id does not grant permission. Local clone: http://127.0.0.1:4000 — see MCP cloud and CLI.
Procedure
- Search:
GET /v1/search?q=or MCPsearch_notes. - Read
coverage(notes_searched,excluded_folders,layer_sequences) before using the hits. Zero hits with coverage is a valid answer. - Read a slice:
GET /v1/notes/{slug}?start_line=&end_line=orread_note, usingline_start/line_endandversion_idfrom the hit. - Edit:
POST /v1/notes/{note}:editor cloudedit_note, with thatversion_id,old_string,new_string,agent_id, and anIdempotency-Key. Reuse a key only when the request body is identical.
Search response
q=Paddle on the sample vault returns the slug payments-provider-decision. The body is not in this payload. private/ is named in excluded_folders. content_hash is the full SHA-256 of the ranked chunk’s note version.
Retry when the version moved
A staleversion_id is 409 VERSION_MOVED. That failure does not store the idempotency key. Follow hint:
GET /v1/notes/{note}to read the currentversion_id, then retry:editwith thatversion_idand a freshIdempotency-Key.
version_id, and submit the changed :edit with a new Idempotency-Key. Reuse a key only for an identical retry of a request that already returned a receipt. A different body for a key that already has a receipt is 409 IDEMPOTENCY_KEY_REUSED.
Receipts
A fresh vault queues agent writes.status: "queued" means the note has not changed. Record and report pending_id. In authenticated mode, GET /v1/writes/{id} requires notes.review: poll only with that permission. With a write-only token, hand the ID to a reviewer and report that receipt inspection requires review permission. Do not approve your own proposal or request additional review permission merely to finish the task. When auth is off, the permission check is skipped.
The API accepts review-scoped personal tokens for :approve and :reject; human-controlled approval is the agent workflow rule, not a human-only credential restriction. Access tokens explains permissions and recovery from revoked or expired tokens.
status: "applied" means the operation completed; unchanged: true means no new version was created. HTTP create/PATCH receipts include note in the GET shape without lines. Cloud MCP applied receipts include version and sequence fields without that embedded note; queued MCP receipts omit the HTTP slug. The JSON below illustrates HTTP receipts. Pass committed_seq as min_seq on the next search when you need to read your own write.
What every retrieval keeps
- Citations, not dumps. Hits are pointers. Fetch only what you need.
- Coverage. Searched count, named exclusions, why the set is partial. Silent gaps are the failure mode Ela refuses.
- Determinism. Same query, same
index_versionandranker_version, same hits. - Vault isolation. Every query is scoped to one
vault_id. - Zero is valid. Empty results plus coverage beat padded noise.
- Cloud paths do not return
private/plaintext. Sync still stores ciphertext. Local MCP can readprivate/. See Privacy.
Machine-readable entry
This host serves/llms.txt, /llms-full.txt, and /skill.md. The wire contract is OpenAPI 3.1 (GET https://api.elanotes.com/openapi.json; this site’s copy is the API reference).
Typed clients: TypeScript SDK and Python SDK. Workspace packages, not published.