Management REST API

The management REST API lets scripts, CI pipelines and other services do what the web UI does for resources: create, read, update, start, stop and delete RAG Topics, GraphRAG Topics and Agents (with existing pipelines attached), and look up the AI servers, Docling servers, vector databases and graph databases they are built on. Pipelines themselves are built in the Pipeline Designer and cannot be created or modified through the API.

This is a different API from the one in RAG Topics → REST API. That page covers chatting with and uploading to a running topic container. This page covers managing the resources themselves, on the management app.

The interactive reference — every endpoint, every field, with a Try it out button — is at /swagger-ui.html on your installation (the raw OpenAPI document is /v3/api-docs).

1 · Get a token

The API is authenticated with personal access tokens.

  1. Your user needs the API_ACCESS permission (Admin → Roles). Without it the API Tokens section does not appear, and existing tokens stop working.

  2. Open Profile → API Tokens → Create Token, give it a name and pick an expiry.

  3. Copy the token (it starts with kfp_). It is shown once — only a fingerprint is stored, so a lost token cannot be recovered; revoke it and create a new one.

Send it on every request:

curl -H "Authorization: Bearer kfp_…" https://fabric.example.com/api/v1/topics

A token acts as you, with your current roles: removing a role or disabling your account takes effect on the next request. Revoke tokens you no longer need from the same Profile section. Administrators with USER_MANAGE can see and revoke any user’s tokens under Admin → Users → Edit.

Resetting your password through Forgot password revokes all of your tokens, since a reset often follows a suspected compromise. Create new ones afterwards. Changing your password on the Profile page does not revoke them.

Tokens work the same for local and SSO (OIDC) users.

2 · Permissions

The API reuses the existing permissions — there are no API-specific ones beyond API_ACCESS:

Operation Permission

Any /api/v1 call

API_ACCESS

List / get topics · GraphRAG topics · agents · pipelines

TOPIC_VIEW · GRAPHRAG_VIEW · AGENT_VIEW · PIPELINE_VIEW

Create

TOPIC_CREATE · GRAPHRAG_CREATE · AGENT_CREATE

Update (PATCH)

TOPIC_EDIT · GRAPHRAG_EDIT · AGENT_EDIT (plus the START permission with restart=true)

Start and stop

TOPIC_START · GRAPHRAG_START · AGENT_START

Delete

TOPIC_DELETE · GRAPHRAG_DELETE · AGENT_DELETE

Assign / remove an agent’s pipelines

AGENT_EDIT, and the pipeline must be granted to you

AI servers, Docling servers, vector and graph databases (read-only)

any of SERVER_VIEW · TOPIC_CREATE · TOPIC_EDIT · GRAPHRAG_CREATE · GRAPHRAG_EDIT

Prompt templates (read-only)

any of TOPIC_CREATE · GRAPHRAG_CREATE · CONFIG_VIEW

On top of the permission, you only see resources granted to one of your roles — the same rule as the lists in the UI. A resource you were not granted answers 404, exactly like one that does not exist.

A resource you create is always granted to ADMIN and to every role you hold, plus any role names you list in the request.

3 · Typical flow

T="Authorization: Bearer kfp_…"
API=https://fabric.example.com/api/v1

# Find the building blocks
curl -H "$T" $API/ai-servers
curl -H "$T" $API/ai-servers/<server-id>/models
curl -H "$T" $API/vector-databases

# Create a topic (only the required fields — everything else takes the wizard's defaults)
curl -H "$T" -H "Content-Type: application/json" $API/topics -d '{
  "basics": { "name": "product_docs", "description": "Product manuals", "port": 8101, "roles": ["USER"] },
  "models": {
    "embedding": { "serverId": "<server-id>", "modelId": "nomic-embed-text" },
    "llm":       { "serverId": "<server-id>", "modelId": "qwen3:latest" }
  },
  "vectorDatabaseId": "<vector-database-id>"
}'

# Start it, then poll until it reports RUNNING
curl -H "$T" -X POST $API/topics/<topic-id>/start
curl -H "$T" $API/topics/<topic-id>

Notes:

  • Start, stop and delete are asynchronous. They answer 202 Accepted right away; poll the resource’s GET for its status (STARTING → RUNNING, or ERROR). A deleted resource answers 404 once removal is finished.

  • Create requests are validated by the same rules as the creation wizards. The request body is grouped like the wizard’s steps (basics, models, ingestion, … for a topic; basics, ingestion, vectorSettings, retrieval for a GraphRAG topic).

  • Every topic needs a registered vector database. Take its id from GET /api/v1/vector-databases and send it as vectorDatabaseId (RAG topic) or basics.vectorDatabaseId (GraphRAG topic). There is no built-in store, so a create request without it is rejected.

  • Prompt templates: the quick-fill templates an admin manages under Admin → Prompt Templates are listed at GET /api/v1/prompt-templates. Either copy a template’s content into basics.userSystemPrompt (and adapt it), or pass its id as basics.userSystemPromptTemplateId to use it as-is — for Topics and GraphRAG Topics alike. The content is copied at creation, so editing the template later does not change existing topics. Give one of the two fields, not both.

  • Embedding dimension: omit it and it is probed from the model; if the model cannot be reached the request fails and asks you to specify it.

  • GraphRAG model roles: extraction, dedup, community report, router and follow-up each need either a model ({"serverId": …, "modelId": …}) or {"inheritLanguageModel": true} — the same explicit choice the wizard asks for.

  • Agents: pass existing pipeline ids in pipelineIds. Pipelines they call are assigned too. GET /api/v1/pipelines shows whether each pipeline is deployable and, if not, why. Pipelines themselves are built in the Pipeline Designer, not through the API.

  • Credentials are never returned. Infrastructure responses say hasApiKey / hasCredentials instead.

3a · Updating a resource

PATCH /api/v1/topics/{id}, /graphrag-topics/{id} and /agents/{id} take a JSON Merge Patch (Content-Type: application/merge-patch+json; plain application/json works the same way). Use the same groups and field names as the create request:

# Change two settings, clear the minimum score, leave everything else as it is
curl -X PATCH -H "$T" -H "Content-Type: application/merge-patch+json" $API/topics/<topic-id> -d '{
  "basics":    { "description": "Product manuals, 2026 edition" },
  "retrieval": { "topK": 5, "minSimilarityScore": null }
}'
  • Send only what changes. An omitted field keeps its value, and null clears an optional setting.

  • A model object is replaced as a whole. Send {"serverId": …, "modelId": …} complete, or {"inheritLanguageModel": true}.

  • Restarts. A running resource only picks up a change to its container configuration after a restart. The response carries restartRequired. Add ?restart=true to have the API stop and start the resource for you; this also needs the resource’s START permission and a valid license (without one the patch is refused before anything is saved or stopped). The response’s restarting then says a restart was triggered, and you poll GET for the status.

  • RAG Topics: the embedding model, the vector database and the chunk size/overlap are fixed at creation. A patch touching one is rejected with a message saying so. The chunking strategy and the upload types (ingestion.uploadTypes) can change and apply to the next upload without a restart; documents already ingested are kept. The topic’s LLM overrides (memory and timeouts) are in llmOverrides. Its Prompts tab is prompts: systemPrompt, contextTemplate (must contain {context}), noAnswerResponse, and the container prompts under prompts.overrides by name (e.g. ROUTER); mapping one to null, or to its default text, removes the override. Routing (retrieval.routing) and keyword enrichment (retrieval.keywordEnrichment, HYBRID only) are under retrieval.

  • GraphRAG Topics: every setting is editable, as in the wizard’s edit mode. Each group you send (basics, ingestion, vectorSettings, retrieval, prompts) is validated in full, like a wizard step you visit. Changing the embedding model or the chunk size/overlap of a topic that already holds data leaves old and new vectors inconsistent. Prompt overrides go under prompts.overrides (by prompt name, e.g. EXTRACTION); mapping a prompt to null, or to its default text, removes the override.

  • Docling options (both topic kinds): ingestion.docling.options holds the topic’s Docling conversion settings as one JSON text, the same text as the Docling Options editor in the UI. Comments (//, /* */) are allowed and kept. The settings are sent with every upload, so a change applies to the next upload without a restart. null uses the Docling server’s defaults. Settings this application sets itself (for example to_formats or include_images) are refused. Without a Docling server the topic keeps no options. Because the value is a JSON text inside JSON, escape its quotes: {"ingestion":{"docling":{"options":"{\"do_ocr\": true}"}}}.

  • Agents: name, description, port, roles, chat attachment types and Kubernetes resources. Pipelines are (un)assigned with PUT/DELETE /api/v1/agents/{id}/pipelines/{pipelineId}. A removed pipeline is deleted from a running agent at once; a stopped or unreachable agent deletes it on its next start. The DELETE response’s runningAgent says which: REMOVED, NOT_RUNNING or UNREACHABLE.

  • Roles: ADMIN is always kept. For GraphRAG Topics your own roles are kept too, as in the wizard.

4 · Errors

Errors are JSON problem documents with a stable code:

Status code Meaning

400

VALIDATION_FAILED

See violations: [{field, message}] — field is the path in your request

400

MALFORMED_REQUEST

Unreadable JSON, unknown enum value or malformed id — or an unknown field, reported as field (its path) with the valid knownFields at that level. Misspelt fields are rejected rather than ignored, so a setting is never silently dropped.

401

—

Missing, unknown, revoked or expired token

403

FORBIDDEN

You lack API_ACCESS or the operation’s permission

404

NOT_FOUND

Unknown id, or not granted to you

409

INVALID_STATE

E.g. starting something that is already running

409

LICENSE_LIMIT

Your license allows no further resource of this kind (limit says how many it allows)

409

LICENSE_REQUIRED

There is no valid license. Creating and starting are refused until an administrator enters a key under Admin → License

415

UNSUPPORTED_MEDIA_TYPE

The body was not sent as JSON (application/json, or application/merge-patch+json for a PATCH); the response’s Accept header lists what the operation takes

502

REGISTRATION_FAILED

A running agent rejected a pipeline being assigned to it

{
  "status": 400,
  "code": "VALIDATION_FAILED",
  "detail": "The request failed validation — see 'violations'.",
  "violations": [
    { "field": "basics.name", "message": "A topic with this name already exists" }
  ]
}