Docs / Developers

REST API

Create lenses, add knowledge, and track ingestion from your own code with the Mindola REST API v1.

The REST API lets you create and manage lenses from your own code. It is small and early: create a lens, list your lenses, add knowledge, and poll ingestion status. More endpoints are coming. All requests go to the base URL https://app.mindola.ai.

If you would rather create lenses from an AI assistant, use the MCP server instead. Runnable scripts for every endpoint live in the open-source repo at github.com/Mindola-ai/mcp-server.

Authentication

Every request needs an API key in the Authorization header:

Authorization: Bearer mnd_your_api_key_here

Keys start with mnd_ followed by 40 hex characters. You create them in the app: open Settings then API & keys. Whether developer access is included depends on your plan; the app shows what your plan includes.

A few things to know about keys:

  • The full key is shown once, at creation. Copy it right away, because Mindola stores only a SHA-256 hash of it.
  • The first 12 characters are kept as a display prefix so you can tell your keys apart.
  • Revoking a key records a timestamp, so revocations are auditable. Requests with a revoked key return 401.

Treat a key like a password. Keep it on the server side, never in client-side code or public repos, and revoke it if you think it leaked.

You can also manage keys over HTTP. These key-management endpoints use your logged-in browser session, not an mnd_ key: POST /api/account/api-keys with an optional { "name" } returns 201 with { id, key, prefix } (the full key appears only in this response), GET /api/account/api-keys lists your keys as prefixes and metadata, and DELETE /api/account/api-keys/:id revokes a key.

Rate limits

Write endpoints allow 30 requests per minute per key. Above that the API returns 429; back off and retry. For bulk ingestion, batch up to 50 items per call instead of sending many small requests.

How ingestion works

Knowledge is not searchable the moment you send it. Each item is queued, then a background pipeline parses it, splits it into chunks, and embeds it for retrieval. The pattern:

  1. Send items with POST /api/v1/lenses (inline knowledge) or POST /api/v1/lenses/:id/knowledge. The response tells you how many sources were queued.
  2. Poll GET /api/v1/lenses/:id. The knowledge object reports total, ready, pending, and failed counts.
  3. When pending is 0, ingestion is done. ready items are live and the lens answers from them. failed items could not be processed (for example, a URL that could not be fetched); re-submit those with cleaner content or a different URL.

Polling every few seconds is fine. Text items usually finish quickly; URLs take longer because the page has to be fetched first.

Create a lens

POST /api/v1/lenses creates a lens, optionally seeded with knowledge in the same call. name is required. greeting (the first message visitors see), context (extra grounding that shapes how the lens answers), and knowledge (up to 50 items) are optional. Each knowledge item is { type, content, title? }: type is "text" or "url" (the only two types the API accepts), content is the text itself or the URL to fetch, and title is a short label shown in citations.

curl -s https://app.mindola.ai/api/v1/lenses \
  -H "Authorization: Bearer mnd_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Product docs assistant",
    "greeting": "Hi, ask me anything about the product.",
    "knowledge": [
      { "type": "text", "title": "Refund policy", "content": "Refunds are available within 30 days of purchase." },
      { "type": "url", "title": "Getting started", "content": "https://example.com/docs/getting-started" }
    ]
  }'

Returns 201 Created:

{
  "id": "V1StGXR8_Z5jdHi6B-myT",
  "token": "YOUR_LENS_TOKEN",
  "shareUrl": "https://mindola.ai/me/YOUR_LENS_TOKEN",
  "sourcesQueued": 2
}

token is the share token, the part of the share URL after /me/. It is a long random hex string; a readable custom slug can be set later in the app. The page at shareUrl is live right away, but it can only answer from knowledge once ingestion finishes.

List your lenses

GET /api/v1/lenses returns the lenses on your account, newest first, up to 100.

curl -s https://app.mindola.ai/api/v1/lenses \
  -H "Authorization: Bearer mnd_your_api_key_here"

Returns 200 OK with { "lenses": [ { "id", "name", "shareUrl", "createdAt" } ] }.

Get one lens

GET /api/v1/lenses/:id fetches one lens with its knowledge counts. This is the endpoint you poll to track ingestion.

curl -s https://app.mindola.ai/api/v1/lenses/YOUR_LENS_ID \
  -H "Authorization: Bearer mnd_your_api_key_here"

Returns 200 OK:

{
  "id": "V1StGXR8_Z5jdHi6B-myT",
  "name": "Product docs assistant",
  "shareUrl": "https://mindola.ai/me/YOUR_LENS_TOKEN",
  "knowledge": { "total": 2, "ready": 1, "pending": 1, "failed": 0 }
}

Add knowledge

POST /api/v1/lenses/:id/knowledge adds 1 to 50 more items to an existing lens, with the same item shape as create. Use it to grow the knowledge base over time, for example when your material changes.

curl -s https://app.mindola.ai/api/v1/lenses/YOUR_LENS_ID/knowledge \
  -H "Authorization: Bearer mnd_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "type": "url", "title": "Changelog", "content": "https://example.com/docs/changelog" }
    ]
  }'

Returns 202 Accepted with { "sourcesQueued": 1 }. The 202 reflects how ingestion works: the items are accepted and queued, not yet ready. Poll GET /api/v1/lenses/:id until knowledge.pending is 0.

Errors

StatusMeaning
400Invalid JSON, missing name on create, or an empty items array.
401Missing, malformed, or revoked API key.
404The lens does not exist or does not belong to your account.
409The lens has no topic scope, so knowledge cannot be attached to it.
429Rate limited: more than 30 write requests in a minute. Back off and retry.
500The create operation failed on the server. Safe to retry.

Not in v1 yet

  • No delete-lens endpoint. Manage lenses you created by mistake in the app.
  • No webhooks. Poll GET /api/v1/lenses/:id for ingestion status.
  • No official SDK packages. Plain HTTP is the supported path: curl, fetch, requests, or any HTTP client you already use. Working scripts in shell, Node, and Python live in the repo; see Examples.
  • Two knowledge item types only, text and url. The app supports more source types (PDF documents, Q&A pairs) that the API does not expose yet.