> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.lumenia.net/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.lumenia.net/_mcp/server.

# General concepts

## The hierarchy

```
Your company  (your API key — internally called a "Partner")
├── Prompt templates  (id → templateId; versioned, assignable to any workspace)
└── Account  (id → X-Account-Id header)
    └── Organization  (id → orgId in URL)
        ├── Workspaces  (id → workspaceId in URL)
        │   └── Integrations  (voice, WhatsApp, Telegram)
        ├── Documents   (id → documentId; organized in folders)
        └── Tools       (id → toolId)
```

Every API call carries enough context to resolve a path through this tree:

| Layer           | How it's identified                                                 |
| --------------- | ------------------------------------------------------------------- |
| Your company    | API key (Bearer token)                                              |
| Account         | `id` → `X-Account-Id` header                                        |
| Organization    | `id` → `{orgId}` in the URL path                                    |
| Workspace       | `id` → `{workspaceId}` in the URL path                              |
| Document        | `id` → `{documentId}` in the URL path                               |
| Tool            | `id` → `{toolId}` in the URL path                                   |
| Prompt template | `id` → `{templateId}` in the URL path; its versions → `{versionId}` |

## Identifiers are opaque

Every resource returns an `id` — a UUID. That `id` is the **only** way the API addresses a resource.

> **Info**
>
> Take the `id` a resource returns and pass it back **as-is** — in the URL path or the `X-Account-Id` header. Do not construct, parse, hex-encode, or otherwise transform ids. There is no separate "slug" form to worry about.

You obtain ids from the list and detail endpoints, for example:

* Accounts — `GET /v1/accounts`
* Organizations — `GET /v1/organizations` (scoped by `X-Account-Id`)
* Workspaces — `GET /v1/organizations/{orgId}/workspaces`
* Documents — `GET /v1/organizations/{orgId}/documents`
* Prompt templates — `GET /v1/prompt-templates` (partner-level: no `X-Account-Id`)

## Account scoping

Account-scoped routes require the `X-Account-Id` header, and the resource in the URL must belong to that account:

* The account must be owned by your company (partner), or you get `403`.
* The org/workspace/document/tool must live under that account, or you get `404` — a valid id from a different account will **not** resolve.

This is by design: the same key can serve many accounts, and the header is what selects which one a request applies to.

## Documents and folders

A **document** is a file uploaded into an organization's storage. Documents are organized into **folders** within the org:

* List folders with `GET /v1/organizations/{orgId}/folders`; create one with `POST /v1/organizations/{orgId}/folders`.
* If you upload without naming a folder, the document lands in `custom-documents`, the catch-all for unfiled docs.
* The target folder must already exist before you upload into it.

A document's `id` is stable and shared: the same id identifies the org document **and** every workspace that has it embedded. You address the document by that one id everywhere.

Only single-document file types are accepted for upload: `pdf`, `docx`, `pptx`, `odt`, `odp`, `txt`, `md`, `rst`, `adoc`, `org`, `html`, `csv`, `epub`.

## Workspaces and embedding

Uploading a document does **not** automatically make it queryable. To use a document in a workspace, embed it:

```
PUT /v1/workspaces/{workspaceId}/documents/{documentId}
```

Notes:

* The document must belong to the same organization as the workspace.
* Embedding is **idempotent** — re-embedding a document that is already embedded in the workspace is a no-op and returns success.
* Remove an embedding with `DELETE /v1/workspaces/{workspaceId}/documents/{documentId}` (this detaches it from the workspace; the org document itself is unaffected).

## Workspace integrations

Each workspace can connect to external channels, each managed under `/v1/workspaces/{workspaceId}/integrations/...`:

* **voice** — a phone assistant (a LumenOne-owned routing number the customer forwards their line to)
* **whatsapp** — WhatsApp Business
* **telegram** — a Telegram bot

Reading a workspace (`GET /v1/workspaces/{workspaceId}`) inlines each channel's status. A channel that is not set up reads `{ connected: false }`, and secret tokens are never returned.

## Go deeper

Each resource has its own guide under **Core concepts**:

* [Partner](/documentation/core-concepts/partner) — your company, the principal behind the API key
* [Accounts](/documentation/core-concepts/accounts) — a customer container and the value behind `X-Account-Id`
* [Organizations](/documentation/core-concepts/organizations) — the tenant boundary
* [Workspaces](/documentation/core-concepts/workspaces) — settings, knowledge, tools, and channels
* [Documents & knowledge base](/documentation/core-concepts/documents) — org-shared uploads, embedding, and what deletion does
* [Tools](/documentation/core-concepts/tools) — HTTP actions, calling them from the prompt, and using their responses
* [Prompt templates](/documentation/core-concepts/prompt-templates) — partner-owned, versioned prompts rolled out to many workspaces
* [Voice integration & routing numbers](/documentation/core-concepts/voice-integration) — phone assistants and the number pool
* [Call logs](/documentation/core-concepts/call-logs) — read-only records of handled voice calls
* [WhatsApp integration](/documentation/core-concepts/whatsapp-integration)
* [Telegram integration](/documentation/core-concepts/telegram-integration)