Skip to content

API keys and the API ​

The Genie API lets your own applications and scripts ask Genie questions, search knowledge bases and add documents. Each application signs in with an API key that a workspace owner creates in Settings. This page shows how to create a key, what a key can and cannot reach, and one complete example: ask a question, stream the answer and read its citations.

Create an API key ​

You need the Owner role: only owners see the API page.

  1. Open Settings → API (in the Publish & integrations group).
  2. Under API Keys, click Create API Key.
  3. In Name, say which application uses the key, for example Intranet portal.
  4. Under Access type, keep Scoped access.
  5. Under Capabilities, select only what the application needs (see the table below). A new key starts with Retrieve knowledge bases, Chat and Read agents.
  6. Under Knowledge bases, choose the knowledge bases the key may use, for example Human resources. Leave it empty to allow every knowledge base in the workspace.
  7. Click Create API Key.
  8. In the list, click the copy button on the key's row and store the key in your application's secret store. Keys start with sk-.
Screenshot coming soonSettings → API: where the workspace's API keys are createdwebsite-docs/public/screenshots/en/api-keys.png
Settings → API: where the workspace's API keys are created

To change a key's name, capabilities or knowledge bases, click the edit button on its row (Edit API key). Changes apply at once and the key value stays the same. To revoke a key, click Delete: every integration that uses it stops working immediately.

Choose capabilities ​

CapabilityWhat the key can do
Retrieve knowledge basesSearch and read the selected knowledge bases. It cannot chat or change anything.
ChatCreate its own conversations, ask questions and list agents.
Read agentsList agents and read their details and suggested questions.
Write KB contentUpload documents and edit content in the selected knowledge bases. It cannot create or empty a knowledge base.
Message historySearch the key's own past conversations (with a user identity, that user's). It never reaches other people's conversations.

The other capabilities (managing knowledge bases, agents, MCP services, data sources, models, channels, members and workspace settings) and Workspace full access are for administration tools. Give them only to a trusted application that runs on a server. Workspace full access ignores the knowledge base list.

What a key can and cannot reach ​

  • Knowledge bases: only those selected on the key. A request that names another knowledge base is refused; when Genie or an agent picks knowledge bases itself, it keeps to the key's list.
  • Documents: unrestricted documents only. A document with document permissions is never searched or cited for an API key, whatever its capabilities, including Workspace full access.
  • Databases and Power BI: not available. Genie answers API questions from documents and, when allowed, the web.
  • Code: Genie does not run code in a sandbox for an API key.
  • Features for signed-in people only: sharing and exporting conversations, analytics, managing API keys.

A key acts as an application, not as an employee. Sending a user ID (see Identify your users) keeps each user's conversations apart, but it does not give the key that person's document permissions. The conversations a key starts belong to it: the workspace's admins cannot read them in Genie.

The base URL ​

The API Base URL field on the API page shows the address to call, for example https://genie.contoso.test/api/v1. Every request sends the key in the X-API-Key header. Requests and responses are JSON; answers stream as server-sent events.

To try a call without writing code, click Open Playground under API Playground on the same page. It creates a conversation and asks a test question, using an API key from the list.

Example: ask a question and stream the answer ​

This example asks Genie, the default assistant, a question about Contoso's leave policy with a key that has the Chat capability.

  1. Set the base URL and your key:

    bash
    GENIE_API=https://genie.contoso.test/api/v1
    GENIE_API_KEY=sk-...   # the key you copied
  2. Create a conversation:

    bash
    curl -s -X POST "$GENIE_API/sessions" \
      -H "X-API-Key: $GENIE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"title":"Annual leave"}'

    The response contains the conversation ID in data.id:

    json
    {"success":true,"data":{"id":"8b6f2c1e-4d0a-4c55-9a51-2f3e7d9c0b12","title":"Annual leave"}}

    The real response has more fields; you only need data.id.

  3. Ask the question in that conversation:

    bash
    SESSION_ID=8b6f2c1e-4d0a-4c55-9a51-2f3e7d9c0b12
    curl -N -X POST "$GENIE_API/agent-chat/$SESSION_ID" \
      -H "X-API-Key: $GENIE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"How many days of annual leave does a new employee get?","agent_id":"builtin-auto","agent_enabled":true,"channel":"api"}'

    builtin-auto is Genie, the default assistant: it chooses the knowledge bases and tools itself, as in the web app. To ask a specific agent, put its ID instead; GET $GENIE_API/agents lists the agents with their IDs. -N makes curl print the answer as it arrives.

  4. Read the stream. Each event is an event:message line followed by a data: line with a JSON object (shortened here):

    text
    event:message
    data:{"response_type":"agent_query","content":"","done":false,"session_id":"8b6f2c1e-…","assistant_message_id":"c41d9e07-…"}
    
    event:message
    data:{"response_type":"answer","content":"A new employee gets 12 days of annual leave a year","done":false}
    
    event:message
    data:{"response_type":"answer","content":" <kb doc=\"Employee handbook\" chunk_id=\"5a1c…\" kb_id=\"3d7f…\" />.","done":false}
    
    event:message
    data:{"response_type":"references","content":"","done":false,"knowledge_references":[{"id":"5a1c…","knowledge_title":"Employee handbook","knowledge_id":"9e2b…","knowledge_base_id":"3d7f…","content":"Employees receive 12 days of paid annual leave per year…","score":0.82}]}
    
    event:message
    data:{"response_type":"complete","content":"","done":true}

Read the answer and its citations ​

Handle the events by their response_type:

response_typeWhat it carriesWhat to do with it
agent_querysession_id and assistant_message_idKeep the message ID if you may need to stop the answer.
answerThe next piece of the answer in contentAppend it to the answer text, in order.
referencesknowledge_references: the passages the answer citesShow them as sources.
errorWhy the answer failed, in contentShow an error.
completeThe end of the answer (done is true)Stop reading.
thinking, tool_call, tool_result and othersGenie's working stepsOptional: ignore them if you only need the answer.

Citations sit inside the answer text as tags:

  • <kb doc="…" chunk_id="…" kb_id="…" /> cites a passage of a document. doc is the document title; chunk_id matches the id of an entry in knowledge_references, whose content is the cited passage and knowledge_title the document.
  • <web url="…" title="…" /> cites a web page.

Turn the tags into links or footnotes in your application, or remove them if you only show plain text.

To ask a follow-up question, send another agent-chat request with the same conversation ID. To read the whole conversation later, call GET $GENIE_API/messages/$SESSION_ID/load: each answer has its content and knowledge_references.

Identify your users (optional) ​

If your application serves many employees with one key, tell Genie who is asking so that each person's conversations stay separate. On the API page, under User identity mode:

  • Workspace only (default): all calls share one identity.
  • Direct user ID: send the user's ID in the X-External-User-ID header. Use it only for calls from your own server, never from a browser.
  • Signed token: your server signs a short-lived token (an HS256 JWT) for the user with the HMAC secret and sends it in the X-External-User-Token header. Use this for applications your users run themselves.

The page shows a signing example and a request example for the mode you choose.

Good to know ​

  • Never put an API key in a web page, a mobile app or a public code repository. To put Genie on a web page, use the website widget.
  • Common errors: 401 means the key is missing, wrong or deleted; 403 means the key lacks the capability or the knowledge base; 409 means an answer is still being written in that conversation; 429 means the workspace's monthly budget is used up.
  • To stop an answer, call POST $GENIE_API/sessions/$SESSION_ID/stop with {"message_id":"<assistant_message_id>"}.
  • To get matching passages without an answer, for example for your own search page, use POST $GENIE_API/knowledge-search with a key that has Retrieve knowledge bases.
  • The complete endpoint reference is not on this site. Ask your Genie provider for it.