Skip to content
On this page

API Reference

Complete reference for all Canny Bot API endpoints.

Base URL

https://api.canny.bot/api

Authentication

Include one of the following with every request:

API Key (Query Parameter):

?api_key=<your_api_key>

API Key (Header):

x-api-key: <your_api_key>

Widget Endpoints

Generate Widget ID

Create a new widget for your website.

POST /widget/generate
x-api-key: <your_api_key>

Response:

json
{
  "data": {
    "widgetId": "wgt_123_abc456",
    "embedCode": "<script src=\"...\"></script>"
  }
}

Get Widget Script

Retrieve the embeddable widget JavaScript.

GET /widget/script/:widget_id

Parameters:

  • widget_id (path): Widget ID

Response: JavaScript code (Content-Type: application/javascript)


Get Widget Info

Retrieve current widget configuration.

GET /widget/info
x-api-key: <your_api_key>

Response:

json
{
  "data": {
    "widgetId": "wgt_123_abc456",
    "embedCode": "<script src=\"...\"></script>",
    "color": "#667eea",
    "greeting": "Hello! How can I help you today?",
    "borderRadius": 16,
    "buttonRadius": 50,
    "buttonText": "Chat",
    "font": "Arial",
    "title": "Chat with us"
  }
}

Customize Widget

Update widget appearance and behavior.

PUT /widget/customize
x-api-key: <your_api_key>
Content-Type: application/json

{
  "widget_color": "#667eea",
  "widget_greeting": "Hello!",
  "widget_border_radius": 16,
  "widget_button_radius": 50,
  "widget_button_text": "Chat",
  "widget_font": "Arial",
  "widget_title": "Chat with us"
}

Response:

json
{
  "data": {
    "success": true
  }
}

Chat (Non-Streaming)

Send a message to the widget chat.

POST /widget/chat
x-api-key: <your_api_key>
Content-Type: application/json

{
  "widgetId": "wgt_123_abc456",
  "sessionId": "sess_abc123",
  "message": "What is your return policy?"
}

Response:

json
{
  "data": {
    "response": "Our return policy allows returns within 30 days...",
    "sessionId": "sess_abc123"
  }
}

Chat Stream

Send a message and receive streaming response.

POST /widget/chat/stream
Content-Type: application/json

{
  "widgetId": "wgt_123_abc456",
  "sessionId": "sess_abc123",
  "message": "What is your return policy?"
}

Response Format (Server-Sent Events):

data: {"type":"sources","sources":[...]}
data: {"type":"content","content":"Our return "}
data: {"type":"content","content":"policy..."}
data: {"type":"done"}

Semantic Search Endpoints

Find documents matching a query.

GET /semantic-search/search?query=<query>&limit=5&threshold=0.1
x-api-key: <your_api_key>

Query Parameters:

  • query (required): Search query
  • limit (optional): Max results (default: 5)
  • threshold (optional): Relevance threshold 0-1 (default: 0.1)
  • contentType (optional): Filter by content type

Response:

json
{
  "data": [
    {
      "id": "chunk_123",
      "title": "Return Policy",
      "textSnippet": "We accept returns within 30 days...",
      "fullContent": "Full content...",
      "score": 0.87,
      "documentId": "doc_1",
      "contentType": "page"
    }
  ],
  "meta": {
    "count": 1
  }
}

Answer

Get an AI-generated answer based on search results.

GET /semantic-search/answer?query=<query>&limit=5&threshold=0.1
x-api-key: <your_api_key>

Query Parameters:

  • query (required): Question
  • limit (optional): Source documents to use (default: 5)
  • threshold (optional): Relevance threshold (default: 0.1)
  • contentType (optional): Filter by content type

Response:

json
{
  "data": {
    "answer": "You can return items within 30 days...",
    "sources": [
      {
        "id": "chunk_123",
        "title": "Return Policy",
        "textSnippet": "We accept returns within 30 days...",
        "score": 0.87
      }
    ]
  },
  "meta": {
    "sourcesCount": 1
  }
}

Answer Stream

Get a streaming AI-generated answer.

GET /semantic-search/answer/stream?query=<query>&limit=5&threshold=0.1
x-api-key: <your_api_key>

Response Format (Server-Sent Events):

data: {"type":"sources","sources":[...],"uniqueDocs":[...]}
data: {"type":"content","content":"You can "}
data: {"type":"content","content":"return items..."}
data: {"type":"done"}

Error Responses

400 Bad Request

json
{
  "error": "Bad Request",
  "message": "Query param is required"
}

401 Unauthorized

json
{
  "error": "Unauthorized",
  "message": "Authentication required. Use JWT token or api_key parameter"
}

404 Not Found

json
{
  "error": "Not Found",
  "message": "Widget not found"
}

429 Too Many Requests

json
{
  "error": "Rate limit exceeded",
  "message": "You have exceeded the rate limit of 10 requests per minute for your free plan.",
  "retryAfter": 45
}

500 Internal Server Error

json
{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred"
}

Rate Limits

Rate limits are enforced per plan:

PlanMonthly LimitRequests/Second
Free1001
Pro1,0005
EnterpriseUnlimited20

Rate Limiting

All authenticated API endpoints are subject to rate limiting based on your plan:

PlanRequests/Minute
Free10
Pro100
Enterprise1000

Rate limit information is included in response headers:

X-RateLimit-Limit: 10
X-RateLimit-Remaining: 9
X-RateLimit-Reset: 1703341234
Retry-After: 45

When the rate limit is exceeded, the API returns a 429 status code with retry information.


Response Codes

CodeMeaning
200Success
400Bad Request
401Unauthorized
404Not Found
429Too Many Requests (Rate Limited)
500Server Error