Reference

Documentation

Octulus indexes a website and serves an embeddable agent that answers questions from it. This page covers installation, widget options, the crawler, and the REST API.

1. Install the widget

Index your site on the demo page to get a workspace ID, then paste this before the closing </body> tag:

<script src="https://octulus.com/widget.js"
        data-workspace="ws_your_workspace_id"
        defer></script>

That's the whole installation. The widget renders inside a shadow root, so it can't inherit or leak CSS.

2. Widget options

AttributeDefaultDescription
data-workspaceRequired. The workspace to answer from.
data-accent#5243E9Any CSS colour. Drives the bubble, header and buttons.
data-titleAsk us anythingHeader title inside the panel.
data-greetingGeneric greetingFirst message the visitor sees.
data-positionrightright or left.
data-openfalseOpen the panel on page load.
data-mountCSS selector. Renders inline in that element instead of as a floating bubble.

3. JavaScript API

The widget exposes a small global once loaded:

Octulus.open();                    // open the panel
Octulus.close();                   // close it
Octulus.ask("What does this cost?"); // open and send a question
Octulus.reset();                   // clear the conversation

Useful for wiring the agent to your own "Talk to us" button rather than the default bubble.

4. The crawler

Octulus fetches your site with the user agent OctulusBot/1.0. It reads /sitemap.xml when present, otherwise follows same-origin links breadth-first to a depth of two. Scripts, styles, navigation and footers are stripped before indexing so boilerplate doesn't pollute answers.

Only public pages are indexed. Hosts resolving to private address ranges are rejected, so the crawler can't be pointed at internal infrastructure.

To exclude the crawler from parts of your site, disallow it in robots.txt:

User-agent: OctulusBot
Disallow: /admin/

5. How answers are produced

Each question is matched against your indexed content with BM25 ranking. The top passages — six by default — are passed to Claude Opus 5 along with a system prompt that forbids answering from anything else. Every claim gets a numbered citation resolving to the source page.

If retrieval returns nothing relevant, the agent says the site doesn't cover it and offers a human handoff. That turn is recorded as unanswered and its topic appears in your content gap report.

6. REST API

Base URL https://octulus.com/api. All requests and responses are JSON except the chat stream.

POST /api/index

Start indexing a site. Returns a job ID immediately; crawling continues in the background.

curl -X POST https://octulus.com/api/index \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com"}'

{"jobId":"job_ab12cd34"}

GET /api/index/:jobId

Poll the job. status moves through crawlingindexingready, or lands on error.

{
  "status": "ready",
  "done": 18,
  "total": 25,
  "workspace": {
    "id": "ws_xY9k2",
    "name": "example.com",
    "stats": { "pages": 18, "chunks": 142, "words": 24831 }
  }
}

POST /api/chat

Ask a question. Responds with a Server-Sent Events stream: a meta frame carrying the conversation ID and matched sources, then delta frames of text, then done.

curl -N -X POST https://octulus.com/api/chat \
  -H 'Content-Type: application/json' \
  -d '{"workspaceId":"ws_xY9k2","message":"What does this cost?"}'

event: meta
data: {"conversationId":"cv_7fQ","sources":[{"n":1,"title":"Pricing","url":"..."}]}

event: delta
data: {"text":"Plans start at "}

event: done
data: {"conversationId":"cv_7fQ"}

POST /api/lead

Record a human-handoff request against a conversation.

curl -X POST https://octulus.com/api/lead \
  -H 'Content-Type: application/json' \
  -d '{"workspaceId":"ws_xY9k2","email":"[email protected]","note":"wants a demo"}'

GET /api/dashboard/:workspaceId

Metrics, recent conversations, captured leads and ranked content gaps for a workspace.

GET /api/health

Service status, active model and whether the Claude connection is configured.

7. Rate limits

EndpointLimit
POST /api/index4 per minute per IP
POST /api/chat20 per minute per IP
POST /api/lead10 per minute per IP

Exceeding a limit returns 429 with a Retry-After header.

Need something that isn't here?

Email [email protected].