Chat

Ask questions against a project's documents, stream answers, and record feedback. The endpoints most integrations start and end with.

dev · https://api.dev.oprag.ai

6 endpoints. 4 are reachable without a dashboard session — they are listed in the Integration API — and the other 2 require a Cognito JWT. The badge under each path says which.

GET /v1/public/share/{slug}

Bootstrap the hosted share page for a slug and mint a short-lived chat token.

Auth Public — no credential

Before you call it

  • The project must be live, with shareEnabled and a shareSlug matching this path.
  • accessMode: "public" lets anyone bootstrap. accessMode: "private" first requires a dashboard JWT — Authorization: Bearer, or a Cognito access token — and membership of the project.
  • shareToken is a 15-minute HMAC JWT. Send it to POST /v1/chat as X-Oprag-Share-Token in place of an API key.

Path parameters

Name Type Required Description
slug string Required Public share slug from the project's share settings.

Query parameters

None.Reads the resource named in the path; there is nothing else to select.

Body parameters

None.GET requests carry no body.

Response

200 Success

JSON
{
  "projectId": "proj_abc123",
  "accessMode": "public",
  "displayName": "Support Bot",
  "welcomeMessage": "Hi! Ask me anything about our product.",
  "theme": {
    "primaryColor": "#2563eb",
    "position": "bottom-right",
    "mode": "auto"
  },
  "shareToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "shareTokenExpiresAt": "2026-08-11T16:26:00.000Z"
}

Status codes

Status Meaning
200 Success.
403 The share link is private and the caller is anonymous: { error: "This chat is private", accessMode: "private" }.
404 { error: "Share link not found" } — unknown slug, share turned off, or an archived project.
429 Rate limited. See rate limits.
503 SHARE_TOKEN_SECRET is not configured, so no token can be minted.

curl

Shell
curl -X GET 'https://api.dev.oprag.ai/v1/public/share/{slug}' \
  -H 'X-Oprag-Key: sk_live_...'
POST /v1/chat

Ask a question against a project's documents and get a grounded answer with citations.

Auth Integration keyEmbed keyShare token Embed keys require a browser `Origin`; share tokens use `X-Oprag-Share-Token`

Path parameters

None.

Query parameters

None.Everything it needs is in the request body.

Body parameters

Name Type Required Description
question string Required The visitor's question. Trimmed; an empty question is rejected with 400.
sessionId string Optional Groups turns into one conversation. Send back the value from the previous response to keep multi-turn context.
conversationId string Optional Server-assigned conversation identifier. Echo it back so the conversation stays one thread in the dashboard.
visitorId string Optional Stable identifier for the end user. Ties leads and escalations to the person who asked.

Request

JSON
{
  "question": "What is your refund policy?",
  "sessionId": "sess_abc123",
  "conversationId": "conv_abc123",
  "visitorId": "visitor_abc123"
}

Responses

200 Answer

The usual branch. type is answer and sources carries the passages it was grounded in.

JSON
{
  "type": "answer",
  "answer": "You can cancel any time from Account → Billing. Refunds are available within 30 days of purchase.",
  "sessionId": "sess_abc123",
  "conversationId": "conv_abc123",
  "visitorId": "visitor_abc123",
  "assistantMessageId": "msg_abc123",
  "sources": [
    {
      "documentTitle": "Billing FAQ",
      "excerpt": "Refunds are available within 30 days of purchase...",
      "location": "billing-faq.pdf",
      "pageNumber": 2,
      "score": 0.89
    }
  ],
  "suggestedFollowUps": ["How long do refunds take?", "Can I pause my plan instead?"]
}

200 Lead capture prompt

Returned when smart lead capture is enabled and the documents cannot answer. There is no answer field on this branch — branch on type before reading it.

JSON
{
  "type": "lead_capture_prompt",
  "promptMessage": "I could not find that in the docs. Leave your email and someone will follow up.",
  "fields": ["name", "email"],
  "conversationId": "conv_abc123",
  "visitorId": "visitor_abc123",
  "sessionId": "sess_abc123"
}

200 Test key fixture

What an sk_test_ or embed_test_ key returns. It omits type — a legacy-shaped payload that clients treat as the answer branch.

JSON
{
  "answer": "This is a test response from oprag. Your integration is working correctly. Replace this with a live key to get real answers from your documents.",
  "sources": [],
  "conversationId": "conv_abc123",
  "sessionId": "sess_abc123"
}

Status codes

Status Meaning
200 Success.
400 The request body failed validation.
401 Missing, revoked, or wrong-environment key.
403 Origin or IP not allowed for this project.
429 Rate limited. See rate limits.

curl

Shell
curl -X POST 'https://api.dev.oprag.ai/v1/chat' \
  -H 'X-Oprag-Key: sk_live_...' \
  -H 'Content-Type: application/json' \
  -d '{"question": "What is your refund policy?","sessionId": "sess_abc123","conversationId": "conv_abc123","visitorId": "visitor_abc123"}'

SDK equivalent `oprag.chat.ask()`

POST /v1/chat/stream

The same question, answered as a Server-Sent Events stream of tokens.

Auth Integration keyEmbed keyShare token Same auth as `POST /v1/chat`

Path parameters

None.

Query parameters

None.Everything it needs is in the request body.

Body parameters

Name Type Required Description
question string Required The visitor's question. Trimmed; an empty question is rejected with 400.
sessionId string Optional Groups turns into one conversation. Send back the value from the previous response to keep multi-turn context.
conversationId string Optional Server-assigned conversation identifier. Echo it back so the conversation stays one thread in the dashboard.
visitorId string Optional Stable identifier for the end user. Ties leads and escalations to the person who asked.

Request

JSON
{
  "question": "What is your refund policy?",
  "sessionId": "sess_abc123",
  "conversationId": "conv_abc123",
  "visitorId": "visitor_abc123"
}

Response

Status codes

Status Meaning
200 Success.
400 The request body failed validation.
401 Missing, revoked, or wrong-environment key.
403 Origin or IP not allowed for this project.
429 Rate limited. See rate limits.

curl

Shell
curl -X POST 'https://api.dev.oprag.ai/v1/chat/stream' \
  -H 'X-Oprag-Key: sk_live_...' \
  -H 'Content-Type: application/json' \
  -d '{"question": "What is your refund policy?","sessionId": "sess_abc123","conversationId": "conv_abc123","visitorId": "visitor_abc123"}'

SDK equivalent `oprag.chat.stream()`

POST /v1/chat/feedback

Record a visitor's thumbs up or down on an assistant message.

Auth Integration key

Before you call it

  • messageId is the assistantMessageId from the answer being rated.
  • visitorId becomes required once the conversation already has one.
  • Respects the widget's feedbackEnabled setting, which defaults to on, and is rate limited per IP.

Path parameters

None.

Query parameters

None.Everything it needs is in the request body.

Body parameters

Name Type Required Description
conversationId string Required Conversation this relates to.
messageId string Required The assistantMessageId from the answer being rated.
rating "up" | "down" Required up or down.
visitorId string Optional Stable identifier for the end user.

Request

JSON
{
  "conversationId": "conv_xyz789",
  "messageId": "msg_abc123",
  "rating": "up",
  "visitorId": "visitor_001"
}

Response

200 Success

JSON
{
  "ok": true,
  "messageId": "msg_abc123",
  "rating": "up",
  "ratedAt": "2026-08-11T18:00:00.000Z"
}

Status codes

Status Meaning
200 Success.
400 The request body failed validation.
401 Missing, revoked, or wrong-environment key.
403 Origin or IP not allowed for this project.
429 Rate limited. See rate limits.

curl

Shell
curl -X POST 'https://api.dev.oprag.ai/v1/chat/feedback' \
  -H 'X-Oprag-Key: sk_live_...' \
  -H 'Content-Type: application/json' \
  -d '{"conversationId": "conv_xyz789","messageId": "msg_abc123","rating": "up","visitorId": "visitor_001"}'
POST /v1/projects/{projectId}/chat

Ask a question against this specific project, authenticated as a workspace user rather than by a project key.

Auth Cognito JWT member

Path parameters

Name Type Required Description
projectId string Required Project the request applies to. Must belong to the calling workspace.

Query parameters

None.Everything it needs is in the request body.

Body parameters

Name Type Required Description
question string Required The visitor's question. Trimmed; an empty question is rejected with 400.
sessionId string Optional Groups turns into one conversation. Send back the value from the previous response to keep multi-turn context.
conversationId string Optional Server-assigned conversation identifier. Echo it back so the conversation stays one thread in the dashboard.
visitorId string Optional Stable identifier for the end user. Ties leads and escalations to the person who asked.

Request

JSON
{
  "question": "What is your refund policy?",
  "sessionId": "sess_abc123",
  "conversationId": "conv_abc123",
  "visitorId": "visitor_abc123"
}

Response

200 Success

JSON
{
  "answer": "Onboarding starts with account setup and document upload.",
  "sessionId": "sess_abc123",
  "conversationId": "conv_xyz789",
  "sources": [
    {
      "documentTitle": "Onboarding guide",
      "excerpt": "Step 1: Create your workspace and upload documents.",
      "location": "onboarding.pdf",
      "pageNumber": 1,
      "score": 0.88
    }
  ],
  "suggestedFollowUps": [
    "What documents do I need to upload?",
    "How long does indexing take?"
  ]
}

Status codes

Status Meaning
200 Success.
400 The request body failed validation.
401 Missing or expired JWT.
403 The signed-in user's role does not allow this.
404 No such resource in this workspace.
429 Rate limited. See rate limits.

curl

Shell
curl -X POST 'https://api.dev.oprag.ai/v1/projects/{projectId}/chat' \
  -H 'Authorization: Bearer <Cognito JWT>' \
  -H 'Content-Type: application/json' \
  -d '{"question": "What is your refund policy?","sessionId": "sess_abc123","conversationId": "conv_abc123","visitorId": "visitor_abc123"}'

SDK equivalent `oprag.chat.ask()`

POST /v1/projects/{projectId}/chat/stream

The same project-scoped question, streamed as Server-Sent Events.

Auth Cognito JWT member

Path parameters

Name Type Required Description
projectId string Required Project the request applies to. Must belong to the calling workspace.

Query parameters

None.Everything it needs is in the request body.

Body parameters

Name Type Required Description
question string Required The visitor's question. Trimmed; an empty question is rejected with 400.
sessionId string Optional Groups turns into one conversation. Send back the value from the previous response to keep multi-turn context.
conversationId string Optional Server-assigned conversation identifier. Echo it back so the conversation stays one thread in the dashboard.
visitorId string Optional Stable identifier for the end user. Ties leads and escalations to the person who asked.

Request

JSON
{
  "question": "What is your refund policy?",
  "sessionId": "sess_abc123",
  "conversationId": "conv_abc123",
  "visitorId": "visitor_abc123"
}

Response

200 Success

JSON
data: {"type":"chunk","text":"Onboarding starts"}

data: {"type":"chunk","text":" with account setup."}

data: {"type":"sources","sources":[{"documentTitle":"Onboarding guide","excerpt":"Step 1: Create your workspace.","location":"onboarding.pdf","pageNumber":1,"score":0.88}]}

data: {"type":"done"}

Status codes

Status Meaning
200 Success.
400 The request body failed validation.
401 Missing or expired JWT.
403 The signed-in user's role does not allow this.
404 No such resource in this workspace.
429 Rate limited. See rate limits.

curl

Shell
curl -X POST 'https://api.dev.oprag.ai/v1/projects/{projectId}/chat/stream' \
  -H 'Authorization: Bearer <Cognito JWT>' \
  -H 'Content-Type: application/json' \
  -d '{"question": "What is your refund policy?","sessionId": "sess_abc123","conversationId": "conv_abc123","visitorId": "visitor_abc123"}'

SDK equivalent `oprag.chat.stream()`

Ready to ship?

Get started free