API Reference

Chatmount API

Integrate your Chatmount chatbot into any application. Send messages, receive AI-powered responses with source citations, and build custom chat experiences — all through a simple REST API.

The API uses the same RAG pipeline as the embedded widget — your chatbot's training data, system prompt, and behavior are identical across all channels.

Authentication

All API requests require an API key sent in the Authorization header. Keys are scoped to a single chatbot — one key can only query the chatbot it was created for.

Header
Authorization: Bearer cm_live_YOUR_API_KEY

Getting your API key

  1. Go to your chatbot dashboard
  2. Select a chatbot and navigate to the API tab
  3. Click Create API Key, give it a name, and copy the key

Keep your key secret

API keys carry full access to your chatbot. Never expose them in client-side code, public repositories, or browser requests. The API has no CORS headers — it is designed for server-to-server use only.

Key format

All keys start with cm_live_ followed by 32 alphanumeric characters. Keys are shown only once at creation — store them securely. You can rotate or revoke keys at any time from the dashboard.

Availability

API access is available on Plus and Enterprise plans. Free and Go plans do not include API key support. View pricing

Quick Start

Send your first message in under a minute. Replace cm_live_YOUR_API_KEY with your actual key.

Request
curl -X POST https://services.chatmount.co/v1/chat \
  -H "Authorization: Bearer cm_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "What are your business hours?",
    "include_sources": true
  }'
Response
200 OK
{
  "message": "Our business hours are Monday through Friday, 9am to 5pm EST.",
  "sources": [
    {
      "url": "https://example.com/about",
      "title": "About Us"
    }
  ],
  "usage": {
    "credits_used": 1,
    "credits_remaining": 99
  }
}

API Reference

POSThttps://services.chatmount.co/v1/chat

Send a message to your chatbot and receive an AI-generated response based on your training data. The chatbot ID is determined by your API key — each key is scoped to a single chatbot.

Request body

FieldTypeDescription
messagestringThe user's message. Must be 1-2000 characters.
streambooleanEnable Server-Sent Events streaming. Default: false
session_idstringReuse a session ID for multi-turn conversations. The bot remembers prior messages within the same session.
include_sourcesbooleanInclude source document URLs in the response. Default: true

Response body

FieldTypeDescription
messagestringThe chatbot's response message.
sourcesarrayUp to 3 source documents used to generate the response. Each has url and title fields.
usageobjectCredit consumption. credits_used is always 1. credits_remaining shows your monthly balance.

Streaming

Set "stream": true to receive the response as Server-Sent Events (SSE). Tokens are sent as they are generated, giving your users a real-time typing experience.

Event format

Stream Output
data: {"type":"token","content":"Our"}

data: {"type":"token","content":" business"}

data: {"type":"token","content":" hours"}

data: {"type":"token","content":" are"}

data: {"type":"token","content":" Monday-Friday, 9am-5pm."}

data: {"type":"sources","sources":[{"url":"https://example.com/about","title":"About Us"}]}

data: {"type":"done"}

Event types

TypePayloadDescription
token{ content: string }A chunk of the response text. Concatenate all token contents for the full message.
sources{ sources: array }Source documents used for the response. Sent once, after all tokens.
done{}Stream complete. Close the connection.

Streaming examples

cURL
curl -X POST https://services.chatmount.co/v1/chat \
  -H "Authorization: Bearer cm_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --no-buffer \
  -d '{
    "message": "What are your business hours?",
    "stream": true
  }'

Sessions

Use the session_id parameter to maintain conversation context across multiple requests. The chatbot will remember prior messages within the same session, enabling natural multi-turn conversations.

If you don't provide a session ID, each request is treated as an independent conversation. Session IDs can be any string — use your own user or conversation identifiers.

Multi-turn example
# First message
curl -X POST https://services.chatmount.co/v1/chat \
  -H "Authorization: Bearer cm_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "What services do you offer?",
    "session_id": "user-123-session-abc"
  }'

# Follow-up (same session_id — bot remembers context)
curl -X POST https://services.chatmount.co/v1/chat \
  -H "Authorization: Bearer cm_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Tell me more about the first one",
    "session_id": "user-123-session-abc"
  }'

Rate Limits

Rate limits are enforced per API key. Each request consumes 1 credit from your monthly pool (shared with widget chat usage).

PlanRequests / minCredits / month
Plus601,500
Enterprise200Unlimited

Rate limit headers

Every response includes headers to help you manage your request rate:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute for your key.
X-RateLimit-RemainingRequests remaining in the current 60-second window.
X-RateLimit-ResetUnix timestamp (seconds) when the rate limit window resets.

Handling rate limits

  1. 1.Check X-RateLimit-Remaining before each request to avoid hitting the limit.
  2. 2.If you receive a 429 response, wait until X-RateLimit-Reset before retrying.
  3. 3.Implement exponential backoff for retries — start at 1 second, double on each attempt, cap at 30 seconds.

Error Handling

Errors return a JSON body with an error field describing the issue.

Error response
400 Bad Request
{
  "error": "Message must be between 1 and 2000 characters"
}

Error codes

CodeMeaning
400Invalid request — message missing, empty, or exceeds 2000 characters.
401Invalid, revoked, or expired API key.
403API key not authorized for this chatbot, or your IP is not in the key's allowlist.
429Rate limit exceeded, daily message cap reached, or monthly credits depleted.
503Service temporarily overloaded.

Code Examples

Complete working examples in popular languages. All examples include error handling and can be copied directly into your project.

Python

Python
import requests
import json
import os

API_KEY = os.environ.get("CHATMOUNT_API_KEY")
BASE_URL = "https://services.chatmount.co/v1/chat"

def chat(message, stream=False, session_id=None):
    """Send a message and return the response."""
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }
    payload = {
        "message": message,
        "stream": stream,
        "include_sources": True,
    }
    if session_id:
        payload["session_id"] = session_id

    response = requests.post(BASE_URL, headers=headers, json=payload, stream=stream)

    # Handle errors
    if response.status_code == 429:
        reset = response.headers.get("X-RateLimit-Reset")
        print(f"Rate limited. Retry after timestamp: {reset}")
        return None
    response.raise_for_status()

    if not stream:
        return response.json()

    # Streaming
    full_response = ""
    for line in response.iter_lines():
        if line:
            line = line.decode("utf-8")
            if line.startswith("data: "):
                event = json.loads(line[6:])
                if event["type"] == "token":
                    full_response += event["content"]
                    print(event["content"], end="", flush=True)
                elif event["type"] == "sources":
                    print("\n\nSources:")
                    for s in event["sources"]:
                        print(f"  - {s['title']}: {s['url']}")
                elif event["type"] == "done":
                    print()
    return full_response

# Usage
reply = chat("What services do you offer?")
print(reply["message"])

# Streaming
chat("Tell me more", stream=True)

# Multi-turn conversation
chat("What services do you offer?", session_id="session-123")
chat("Tell me more about the first one", session_id="session-123")

Node.js

JavaScript
const API_KEY = process.env.CHATMOUNT_API_KEY;
const BASE_URL = "https://services.chatmount.co/v1/chat";

async function chat(message, { stream = false, sessionId } = {}) {
  const response = await fetch(BASE_URL, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      message,
      stream,
      session_id: sessionId,
      include_sources: true,
    }),
  });

  // Handle errors
  if (response.status === 429) {
    const reset = response.headers.get("X-RateLimit-Reset");
    console.error(`Rate limited. Retry after: ${reset}`);
    return null;
  }
  if (!response.ok) {
    const err = await response.json();
    throw new Error(err.error || `HTTP ${response.status}`);
  }

  if (!stream) {
    return response.json();
  }

  // Streaming
  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let fullResponse = "";

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const chunk = decoder.decode(value);
    for (const line of chunk.split("\n")) {
      if (line.startsWith("data: ")) {
        const event = JSON.parse(line.slice(6));
        if (event.type === "token") {
          fullResponse += event.content;
          process.stdout.write(event.content);
        } else if (event.type === "sources") {
          console.log("\nSources:", event.sources);
        }
      }
    }
  }
  return fullResponse;
}

// Usage
const reply = await chat("What services do you offer?");
console.log(reply.message);

// Streaming
await chat("Tell me more", { stream: true });

// Multi-turn conversation
await chat("What services do you offer?", { sessionId: "session-123" });
await chat("Tell me more about the first one", { sessionId: "session-123" });

cURL

bash
# Non-streaming request
curl -X POST https://services.chatmount.co/v1/chat \
  -H "Authorization: Bearer $CHATMOUNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "What services do you offer?",
    "include_sources": true
  }'

# Streaming request
curl -X POST https://services.chatmount.co/v1/chat \
  -H "Authorization: Bearer $CHATMOUNT_API_KEY" \
  -H "Content-Type: application/json" \
  --no-buffer \
  -d '{
    "message": "What services do you offer?",
    "stream": true
  }'

# With session ID (multi-turn)
curl -X POST https://services.chatmount.co/v1/chat \
  -H "Authorization: Bearer $CHATMOUNT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Tell me more about the first one",
    "session_id": "session-123"
  }'