DocsReference

Complete Documentation

API keys, SDK, and Public API reference for Layerum integrations.

API Keys

API keys are created and managed only through the Layerum platform UI. API and SDK integrations do not create keys directly.

  • Sign in to Layerum and open workspace API Keys.
  • Create key, assign capabilities and scopes, then copy one-time secret.
  • Use secret as Authorization: Bearer lyr_wk_....
  • Rotate/revoke is also done in the same UI page.
bash
# .env
LAYERUM_API_KEY=lyr_wk_xxxxxxxxxxxxxxxxx

Capabilities, Scopes, and Limits

  • Capabilities: query:read, data:ingest, config:manage.
  • Scopes: allowed_entity_ids, allowed_model_config_ids.
  • Limits: rpm_limit, daily_token_limit, optional expires_at.
  • Rotate keeps same key record but issues a new secret.
  • Revoke disables key immediately.

SDK Overview

Official package @layerum-team/rag-sdk is a typed client for public API /v1/*.

npm: https://www.npmjs.com/package/@layerum-team/rag-sdk

bash
npm i @layerum-team/rag-sdk

SDK namespaces: entities, entityTypes, documents, ingestion, query, models.

SDK Client Options

ts
import { LayerumClient } from '@layerum-team/rag-sdk';

const client = new LayerumClient({
  apiKey: process.env.LAYERUM_API_KEY!,
  baseUrl: 'https://api.layerum.com',
  timeoutMs: 30000,
  maxRetries: 2
});
  • apiKey required (lyr_wk_...).
  • baseUrl optional override, default https://api.layerum.com.
  • timeoutMs default 30000.
  • maxRetries default 2 (GET on 429/5xx only).

SDK Error Handling

SDK throws LayerumApiError for API failures.

ts
import { LayerumApiError } from '@layerum-team/rag-sdk';

try {
  await client.query.run({
    entityId: '<entity_uuid>',
    modelConfigId: '<model_config_uuid>',
    query: 'Hello'
  });
} catch (e) {
  if (e instanceof LayerumApiError) {
    console.error(e.status, e.message, e.path, e.method, e.details);
  }
}

SDK: entities

  • list(parentId?: UUID) -> GET /v1/entities; optional client-side filter by parent.
  • tree() -> GET /v1/entities/tree.
  • create(input) -> POST /v1/entities.
  • remove(entityId) -> DELETE /v1/entities/:id.
ts
await client.entities.create({
  entityTypeId: '<entity_type_uuid>',
  name: 'Invoices',
  description: 'Accounting docs',
  parentId: '<optional_parent_uuid>',
  metadata: { team: 'finance' }
});

SDK: entityTypes

  • list() -> GET /v1/entity-types.
  • get(entityTypeId) -> GET /v1/entity-types/:id.
  • create(input) -> POST /v1/entity-types.
  • remove(entityTypeId) -> DELETE /v1/entity-types/:id.
ts
await client.entityTypes.create({
  name: 'project',
  label: 'Project'
});

SDK: documents

  • list({ entityId, allInWorkspace? }) -> GET /v1/entities/:entityId/documents or GET /v1/documents.
  • get(entityId, sourceId) -> GET /v1/entities/:entityId/documents/:id.
  • createText(input) -> POST /v1/entities/:entityId/documents with source_type: "text".
  • createUrl(input) -> POST /v1/entities/:entityId/documents with source_type: "url".
  • upload(input) -> POST /v1/entities/:entityId/documents/upload multipart.
  • uploadInit(input) -> POST /v1/entities/:entityId/documents/upload/init.
  • uploadComplete(input) -> POST /v1/entities/:entityId/documents/upload/complete.
  • uploadDirect(input)-> init + S3 POST + complete.
  • remove({ entityId, sourceId }) -> DELETE /v1/entities/:entityId/documents/:id.
ts
const source = await client.documents.uploadDirect({
  entityId: '<entity_uuid>',
  file: fileBlob,
  fileName: 'large.pdf',
  contentType: 'application/pdf'
});

await client.ingestion.waitUntilReady({
  entityId: '<entity_uuid>',
  sourceId: source.id
});

Important: uploadInit.fileSizeBytes must match uploaded object size exactly.

SDK: ingestion

  • retry({ entityId, sourceId }) -> POST /v1/entities/:entityId/documents/:id/retry.
  • error({ entityId, sourceId }) -> GET /v1/entities/:entityId/documents/:id/error.
  • waitUntilReady({ entityId, sourceId, timeoutMs?, intervalMs? })-> polls document status until completed or failed.

Defaults: timeoutMs = 120000, intervalMs = 2000.

SDK: query

  • run(input) -> POST /v1/query.
  • runDebug(input) -> POST /v1/query/debug.
ts
const result = await client.query.run({
  entityId: '<entity_uuid>',
  modelConfigId: '<model_config_uuid>',
  query: 'Summarize key points',
  topK: 8,
  includeParentScopes: true
});

console.log(result.answer);
console.log(result.citations);

SDK: models

  • listConfigs() -> GET /v1/models.
  • getConfig(id) -> GET /v1/models/:id.
  • createConfig(input) -> POST /v1/models.
  • updateConfig(id, input) -> PATCH /v1/models/:id.
  • removeConfig(id) -> DELETE /v1/models/:id.
  • listDefinitions({ type? }) -> GET /v1/model-definitions?type=....
ts
const configs = await client.models.listConfigs();
const created = await client.models.createConfig({
  name: 'SDK Config',
  llmModelId: '<llm_model_uuid>',
  embeddingModelId: '<embedding_model_uuid>',
});
const embeddings = await client.models.listDefinitions({ type: 'embedding' });

SDK: providers

  • list() -> GET /v1/providers.
  • get(id) -> GET /v1/providers/:id.
  • create(input) -> POST /v1/providers.
  • test(id) -> POST /v1/providers/:id/test.
  • remove(id) -> DELETE /v1/providers/:id.

Public API (/v1)

Authentication for all /v1 endpoints:

http
Authorization: Bearer lyr_wk_xxxxxxxxxxxxxxxxx
  • Key must be active, not revoked, and not expired.
  • Capability checks are enforced (query:read, data:ingest, config:manage).
  • Entity/model scopes and limits are enforced.

API Error Format

json
{
  "statusCode": 400,
  "message": "Validation failed",
  "timestamp": "2026-03-24T12:00:00.000Z",
  "path": "/v1/query",
  "method": "POST",
  "details": {}
}

Public API: Entities

GET/v1/entities
GET/v1/entities/tree
POST/v1/entities

Body

  • entity_type_id (uuid, required)
  • name (string, required, max 200)
  • description (string, optional)
  • parent_id (uuid, optional)
  • metadata (object, optional)

Notes

  • Scoped API keys cannot create root entities unless scope allows it.
DELETE/v1/entities/:id

Public API: Entity Types

GET/v1/entity-types
GET/v1/entity-types/:id
POST/v1/entity-types

Body

  • name (string, required, max 50)
  • label (string, required, max 100)
DELETE/v1/entity-types/:id

Public API: Documents

GET/v1/entities/:entityId/documents
GET/v1/documents
GET/v1/entities/:entityId/documents/:id
POST/v1/entities/:entityId/documents

Body

  • source_type ("file" | "url" | "text", required)
  • display_name (string, required)
  • source_url (string, optional)
  • raw_text (string, optional)
  • visibility ("self" | "self_and_descendants", optional)
  • model_config_id (uuid, optional)
POST/v1/entities/:entityId/documents/upload

Body

  • multipart/form-data
  • file (required)
  • visibility (optional)
  • model_config_id (optional)
POST/v1/entities/:entityId/documents/upload/init

Body

  • file_name (string, required)
  • file_size_bytes (int >= 1, required)
  • content_type (string, optional)
  • visibility ("self" | "self_and_descendants", optional)
  • model_config_id (uuid, optional)
POST/v1/entities/:entityId/documents/upload/complete

Body

  • upload_id (uuid, required)
  • display_name (string, optional)
  • visibility ("self" | "self_and_descendants", optional)
  • model_config_id (uuid, optional)
  • checksum (string, optional)

Notes

  • Uploaded object size must exactly match file_size_bytes declared at upload/init.
DELETE/v1/entities/:entityId/documents/:id
POST/v1/entities/:entityId/documents/:id/retry
GET/v1/entities/:entityId/documents/:id/error

Public API: Models

GET/v1/models
GET/v1/models/:id
POST/v1/models
PATCH/v1/models/:id
DELETE/v1/models/:id
GET/v1/model-definitions

Query

  • type (string, optional)

Public API: Providers

GET/v1/providers
GET/v1/providers/:id
POST/v1/providers
POST/v1/providers/:id/test
DELETE/v1/providers/:id

Public API: Query

POST/v1/query

Body

  • entityId (uuid, required)
  • modelConfigId (uuid, required)
  • query (string, required)
  • topK (number 1..20, optional)
  • includeParentScopes (boolean, optional)
POST/v1/query/debug

Body

  • entityId (uuid, required)
  • modelConfigId (uuid, required)
  • query (string, required)
  • topK (number 1..20, optional)
  • includeParentScopes (boolean, optional)

Notes

  • Returns additional debug metadata when backend provides it.
json
{
  "entityId": "<entity_uuid>",
  "modelConfigId": "<model_config_uuid>",
  "query": "Summarize latest updates",
  "topK": 8,
  "includeParentScopes": true
}

Capacity and Upload Model

Capacity is account-level and can be distributed dynamically across workspaces.

  • Counted usage: entities, documents/data source bytes, chunks, S3 files tied to documents, pending upload reservations.
  • Not counted: audit records, access records, API key metadata, model/provider metadata.
  • Direct upload hardening: capacity reserved at upload/init, object validated at upload/complete, stale sessions are cleaned up.
bash
curl -X POST "https://api.layerum.com/v1/entities/<entityId>/documents/upload/init" \
  -H "Authorization: Bearer lyr_wk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "file_name":"manual.pdf",
    "file_size_bytes":123456,
    "content_type":"application/pdf"
  }'