Datalumo
Docs · Widget API
View markdown

Widget API overview

/api/v1/{organisation}/widgets/{widget}/…

{widget} is the widget's public id. The key you paste into the embed snippet looks like {organisation}/{widget}. That public key is safe to put in the browser; it is not a secret.

#Endpoints

Method Path Purpose Uses answers
GET /config Appearance and behaviour settings No
POST /search Search your content No
POST /chat AI answer (optional streaming) Yes
POST /summarize Short AI summary of top results Yes
POST /events Feedback and click analytics No
* /conversations… History for signed-in visitors No

See Authentication for domain, secret key, and API key rules.

#Config

GET /widgets/{widget}/config

Responses may be cached for up to five minutes.

{
  "type": "chatbot",
  "name": "Help",
  "variant": "bubble",
  "accent_light": "#18181b",
  "accent_dark": "#fafafa",
  "theme": "auto",
  "branding": true,
  "summary": false,
  "speech_input": false,
  "placeholder": "",
  "greeting": "",
  "prompts": [],
  "avatar": null,
  "debounce": 1000,
  "default_language": "en"
}

prompts is chat-only: short suggested questions (max 6) rendered as chips on an empty thread.

branding reflects your plan. On plans that show the Datalumo badge, clients cannot turn it off by ignoring this field.

#Session ids

Search and chat accept an optional session_id. If you omit it, Datalumo creates one and returns it. Reuse the same id from search through clicks and chat so analytics stay connected for that visit.

POST /api/v1/{organisation}/widgets/{widget}/search

Auth: widget domain, widget secret, or organisation API key with search
Widget type: search or chatbot

Search across the sources linked to the widget. Search does not use answer credits.

#Body

Field Type Required Description
query string yes Max 1024 characters
filters object no Optional filters
sort string no Optional sort
limit int no 1-50, default 10
session_id string no Analytics session; created for you if omitted

#Response

{
  "data": [
    {
      "id": "0194b…",
      "external_id": "wp-42",
      "name": "Hello world",
      "url": "https://example.com/hello-world#section",
      "snippet": "…matching text…",
      "score": 0.87,
      "meta": null,
      "thumbnail": "https://example.com/hello-world.jpg"
    }
  ],
  "session_id": "…"
}

url is the link you can show as a citation (page URL, with a section anchor when available).

#Example

curl -sS -X POST \
  -H "Authorization: Bearer $WIDGET_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"query": "how does pricing work", "limit": 5}' \
  "https://datalumo.app/api/v1/{organisation}/widgets/{widget}/search"

#Chat

POST /api/v1/{organisation}/widgets/{widget}/chat

Auth: widget domain, widget secret, or organisation API key with chat
Widget type: chatbot
Billing: uses one answer from your plan. When you have no answers left, the API returns 402 with plain search hits in data (same shape as the search endpoint). No chat model is called. The official embed renders those results in the bubble.

#Body

Field Type Required Description
query string yes Visitor message, max 2048 characters
conversation_id string no Continue an existing conversation
session_id string no Analytics session
browser_language string no Language hint from the visitor's browser
context object no Up to 10 string keys with simple values (for example page URL or title)
user object no { "id": "…", "hash": "…" } signed visitor identity
stream bool no Set true for a streamed response instead of one JSON payload

#JSON response (stream false or omitted)

{
  "data": {
    "text": "…answer in markdown…",
    "conversation_id": "…",
    "answer_id": "…",
    "sources": [
      {
        "id": "0194b…",
        "external_id": "wp-42",
        "name": "Hello world",
        "url": "https://example.com/hello-world",
        "snippet": "…",
        "score": 0.91,
        "meta": null
      }
    ],
    "actions": []
  },
  "session_id": "…"
}

#Streaming ("stream": true)

The response is a stream of server-sent events (text/event-stream):

Event Data When
status { "step": "searching", "query": "…" } Looking up your knowledge sources
status { "step": "web_searching" } Searching allowlisted websites (chat action)
status { "step": "sending" } Calling a configured webhook (chat action)
status { "step": "offering" } Proposing a page action the visitor will confirm
token { "text": "…" } Next piece of the answer
done { "conversation_id", "session_id", "answer_id", "sources": […], "actions": […] } Finished
error { "message": "…" } Something failed mid-stream

#Identity and conversation ownership

  • With a valid user.id and user.hash, the conversation belongs to that verified visitor.
  • Continuing a verified conversation without the same proof returns 403.
  • A bad hash returns 422.

See Conversations for listing history, reading transcripts, keeping conversations, and deletion.

Chatbots can also call optional chat actions you configure in the dashboard (allowlisted web search, signed webhooks, and page actions).

#When to use the embed instead

The official embed already handles streaming, conversation storage, visitor identity, and falling back to search when answers run out. Prefer it in the browser: see Install for mount options, headless mode, and the analytics beacon, or the chat and search product guides. Call these endpoints directly when you build a custom client or need server-side access.

Optional chatbot actions (allowlisted web search, signed webhooks, and page actions) are configured in the dashboard, not on this config endpoint.