Skip to main content
Use the Bag of Words API to add a Bow-powered chat or completion panel to your own product. Your UI creates or reuses a report, streams a completion with fetch, and renders Server-Sent Events as they arrive. This guide is for internal tools, trusted admin panels, and backend-proxied production apps.

What You Need

  • A Bag of Words base URL — e.g. http://localhost:3000 or https://bow.example.com
  • A bow_... API key created in Bag of Words Settings → API Keys
  • Optional data source or agent IDs to attach to the report
  • A browser or backend that can call the Bow API
Do not include /api in the user-facing base URL. Build the API base internally:

For a private internal app, the browser can call Bow directly with an API key. For a public app, proxy requests through your own backend:
Your backend should store the Bow API key, enforce your app’s authorization rules, and stream the Bow SSE response back to the browser. Do not expose long-lived Bow API keys in public client-side code.

Minimum Streaming Flow

  1. Create a report with the data sources your chat should use.
  2. POST a streaming completion to that report.
  3. Parse SSE frames from the response body.
  4. Render assistant text, reasoning, tool progress, and errors from the events.
Reports are the scope for data sources. Attach data sources when creating or updating the report — not in the completion prompt mentions.

Create a Report

Create a report when the user starts a new chat session or when you need a temporary scratch report.

Stream a Completion

Use fetch, not EventSource, because the completion stream is a POST request with custom headers.

SSE Format

Bow sends standard Server-Sent Events:
A blank line ends an event. Multiple data: lines belong to the same event and should be joined with \n. The data: payload is an envelope — parse it like this:
data: [DONE] means the stream is complete.

Tiny SSE Parser


Event Reference

Handle unknown events gracefully — the API may add events over time.

Rendering a Chat UI

Keep the UI reducer small:
  • Store status: idle, streaming, success, or error
  • Store blocks by id
  • Append block.delta.token for assistant text
  • Replace text on block.delta.text
  • Show reasoning inside a collapsible disclosure
  • Show tools as compact rows with name, status, and summary
  • Keep raw JSON behind a disclosure for tool payloads
  • Keep the raw SSE log available in a debug tab

Optional API Requests

Validate an API key:
Load data sources or agents for a picker:
Update a report when the user changes selected data sources:

Error Handling


Copy-Paste cURL


Production Checklist

  • Proxy public integrations through your backend
  • Keep Bow API keys server-side for public apps
  • Use AbortController for the Stop button
  • Persist report IDs if a chat should resume later
  • Attach data sources through report creation or update
  • Keep mentions: [] unless your integration intentionally supports Bow prompt mentions
  • Log raw SSE frames for support and debugging
  • Render unknown future events without crashing