ChatForge Developer API

Build integrations, automate agent management, and access conversation data through the ChatForge REST API.

Quick Start Guide

Get up and running in under two minutes. This guide walks you through making your first API call.

1. Get your API key

Navigate to Dashboard → Settings → API Keys and click Generate Key. Your key will start with cfk_ and will only be displayed once, so copy it immediately and store it securely.

2. Make your first request

Verify your key works by calling the /me endpoint:

curl https://chatforge.aiedge247.com/api/v1/me \
  -H "Authorization: Bearer cfk_your_api_key"
const res = await fetch('https://chatforge.aiedge247.com/api/v1/me', {
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const data = await res.json();
console.log(data);
import requests

res = requests.get(
    'https://chatforge.aiedge247.com/api/v1/me',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())

3. List your agents

curl https://chatforge.aiedge247.com/api/v1/agents \
  -H "Authorization: Bearer cfk_your_api_key"
const res = await fetch('https://chatforge.aiedge247.com/api/v1/agents', {
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const agents = await res.json();
console.log(agents);
import requests

res = requests.get(
    'https://chatforge.aiedge247.com/api/v1/agents',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())

4. Create an agent

curl -X POST https://chatforge.aiedge247.com/api/v1/agents \
  -H "Authorization: Bearer cfk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sales Assistant",
    "greeting": "Hi! How can I help you today?",
    "color": "#6366f1"
  }'
const res = await fetch('https://chatforge.aiedge247.com/api/v1/agents', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cfk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Sales Assistant',
    greeting: 'Hi! How can I help you today?',
    color: '#6366f1'
  })
});
const agent = await res.json();
console.log(agent);
import requests

res = requests.post(
    'https://chatforge.aiedge247.com/api/v1/agents',
    headers={
        'Authorization': 'Bearer cfk_your_api_key',
        'Content-Type': 'application/json'
    },
    json={
        'name': 'Sales Assistant',
        'greeting': 'Hi! How can I help you today?',
        'color': '#6366f1'
    }
)
print(res.json())

Base URL: All endpoints use https://chatforge.aiedge247.com/api/v1 as the base URL.

Authentication

The ChatForge API uses Bearer token authentication. Include your API key in the Authorization header of every request:

Authorization: Bearer cfk_your_api_key

Getting your API key

  1. Log in to your ChatForge Dashboard.
  2. Go to Settings → API Keys.
  3. Click Generate New Key.
  4. Copy the key immediately. It starts with cfk_ and is shown only once.

Keep your API key secret. Do not expose it in client-side code, public repositories, or logs. If your key is compromised, revoke it immediately in the Dashboard and generate a new one.

Key properties

Rate Limits

Rate limits are applied per API key on a rolling one-minute window.

PlanRequests / minBurst
Free / Starter10020 req/sec
Growth / Scale1,000100 req/sec

Rate limit information is returned in response headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1711468800

When you exceed the rate limit, the API returns a 429 Too Many Requests status. Back off and retry after the time indicated in X-RateLimit-Reset (Unix timestamp).

Error Codes

The API uses standard HTTP status codes and returns a consistent JSON error body:

{
  "error": {
    "code": "agent_not_found",
    "message": "No agent found with the given ID.",
    "status": 404
  }
}
StatusCodeDescription
400bad_requestThe request body is malformed or missing required fields.
401unauthorizedMissing or invalid API key.
403forbiddenYour API key does not have permission for this resource.
404not_foundThe requested resource does not exist.
409conflictA resource with the same unique identifier already exists.
422validation_errorThe request body contains invalid field values.
429rate_limitedToo many requests. Check X-RateLimit-Reset header for retry time.
500internal_errorAn unexpected server error occurred. Please retry or contact support.
503service_unavailableThe service is temporarily unavailable. Retry with exponential backoff.

Agents

Agents are the core resource in ChatForge. Each agent represents a chat widget that can be embedded on a website. Agents have a name, greeting message, color theme, and an optional knowledge base.

List all agents

GET /agents

Returns a list of all agents belonging to the authenticated account. Results are ordered by creation date (newest first).

curl https://chatforge.aiedge247.com/api/v1/agents \
  -H "Authorization: Bearer cfk_your_api_key"
const res = await fetch('https://chatforge.aiedge247.com/api/v1/agents', {
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const data = await res.json();
console.log(data);
import requests

res = requests.get(
    'https://chatforge.aiedge247.com/api/v1/agents',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())
Response
{
  "agents": [
    {
      "id": "agt_a1b2c3d4e5",
      "name": "Sales Assistant",
      "greeting": "Hi! How can I help you today?",
      "color": "#6366f1",
      "status": "active",
      "conversations_count": 142,
      "leads_count": 38,
      "knowledge_base": true,
      "created_at": "2026-03-15T08:30:00Z",
      "updated_at": "2026-03-20T14:22:00Z"
    },
    {
      "id": "agt_f6g7h8i9j0",
      "name": "Support Bot",
      "greeting": "Hello! I'm here to help with any questions.",
      "color": "#10b981",
      "status": "active",
      "conversations_count": 89,
      "leads_count": 12,
      "knowledge_base": false,
      "created_at": "2026-03-10T12:00:00Z",
      "updated_at": "2026-03-18T09:15:00Z"
    }
  ],
  "total": 2
}

Create agent

POST /agents

Creates a new agent. The agent is immediately available for embedding after creation.

ParameterTypeDescription
name REQUIREDstringDisplay name for the agent (1-100 characters).
greetingstringInitial message shown when the chat opens. Default: "Hi! How can I help you today?"
knowledge_basestringInitial knowledge content for the agent. Plain text or markdown. Max 50,000 characters.
colorstringHex color code for the widget theme. Default: "#6366f1".
curl -X POST https://chatforge.aiedge247.com/api/v1/agents \
  -H "Authorization: Bearer cfk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sales Assistant",
    "greeting": "Hi! How can I help you today?",
    "knowledge_base": "We sell premium widgets. Pricing starts at $49/mo...",
    "color": "#6366f1"
  }'
const res = await fetch('https://chatforge.aiedge247.com/api/v1/agents', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cfk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Sales Assistant',
    greeting: 'Hi! How can I help you today?',
    knowledge_base: 'We sell premium widgets. Pricing starts at $49/mo...',
    color: '#6366f1'
  })
});
const agent = await res.json();
console.log(agent);
import requests

res = requests.post(
    'https://chatforge.aiedge247.com/api/v1/agents',
    headers={
        'Authorization': 'Bearer cfk_your_api_key',
        'Content-Type': 'application/json'
    },
    json={
        'name': 'Sales Assistant',
        'greeting': 'Hi! How can I help you today?',
        'knowledge_base': 'We sell premium widgets. Pricing starts at $49/mo...',
        'color': '#6366f1'
    }
)
print(res.json())
Response
{
  "id": "agt_k1l2m3n4o5",
  "name": "Sales Assistant",
  "greeting": "Hi! How can I help you today?",
  "color": "#6366f1",
  "status": "active",
  "knowledge_base": true,
  "embed_code": "<script src=\"https://chatforge.aiedge247.com/widget.js\" data-agent=\"agt_k1l2m3n4o5\"></script>",
  "created_at": "2026-03-26T10:00:00Z",
  "updated_at": "2026-03-26T10:00:00Z"
}

Get agent details

GET /agents/:id

Retrieves detailed information about a specific agent, including configuration, embed code, and aggregate stats.

curl https://chatforge.aiedge247.com/api/v1/agents/agt_a1b2c3d4e5 \
  -H "Authorization: Bearer cfk_your_api_key"
const agentId = 'agt_a1b2c3d4e5';
const res = await fetch(`https://chatforge.aiedge247.com/api/v1/agents/${agentId}`, {
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const agent = await res.json();
console.log(agent);
import requests

agent_id = 'agt_a1b2c3d4e5'
res = requests.get(
    f'https://chatforge.aiedge247.com/api/v1/agents/{agent_id}',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())
Response
{
  "id": "agt_a1b2c3d4e5",
  "name": "Sales Assistant",
  "greeting": "Hi! How can I help you today?",
  "color": "#6366f1",
  "status": "active",
  "knowledge_base": true,
  "knowledge_size_bytes": 24500,
  "conversations_count": 142,
  "leads_count": 38,
  "avg_response_time_ms": 1200,
  "embed_code": "<script src=\"https://chatforge.aiedge247.com/widget.js\" data-agent=\"agt_a1b2c3d4e5\"></script>",
  "allowed_domains": ["example.com", "app.example.com"],
  "created_at": "2026-03-15T08:30:00Z",
  "updated_at": "2026-03-20T14:22:00Z"
}

Update agent

PUT /agents/:id

Updates an existing agent. Only the fields you include in the request body will be changed; all other fields remain untouched.

ParameterTypeDescription
namestringUpdated display name (1-100 characters).
greetingstringUpdated greeting message.
knowledge_basestringReplaces the full knowledge base content. Max 50,000 characters.
colorstringHex color code for the widget theme.
allowed_domainsstring[]List of domains where the widget is allowed to load.
curl -X PUT https://chatforge.aiedge247.com/api/v1/agents/agt_a1b2c3d4e5 \
  -H "Authorization: Bearer cfk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sales Assistant v2",
    "greeting": "Welcome! Ask me anything about our products.",
    "color": "#10b981"
  }'
const agentId = 'agt_a1b2c3d4e5';
const res = await fetch(`https://chatforge.aiedge247.com/api/v1/agents/${agentId}`, {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer cfk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Sales Assistant v2',
    greeting: 'Welcome! Ask me anything about our products.',
    color: '#10b981'
  })
});
const agent = await res.json();
console.log(agent);
import requests

agent_id = 'agt_a1b2c3d4e5'
res = requests.put(
    f'https://chatforge.aiedge247.com/api/v1/agents/{agent_id}',
    headers={
        'Authorization': 'Bearer cfk_your_api_key',
        'Content-Type': 'application/json'
    },
    json={
        'name': 'Sales Assistant v2',
        'greeting': 'Welcome! Ask me anything about our products.',
        'color': '#10b981'
    }
)
print(res.json())
Response
{
  "id": "agt_a1b2c3d4e5",
  "name": "Sales Assistant v2",
  "greeting": "Welcome! Ask me anything about our products.",
  "color": "#10b981",
  "status": "active",
  "knowledge_base": true,
  "updated_at": "2026-03-26T11:30:00Z"
}

Deactivate agent

DELETE /agents/:id

Deactivates an agent. The agent's widget will stop responding to visitors immediately. Conversation history and leads are preserved. This action can be reversed by contacting support.

curl -X DELETE https://chatforge.aiedge247.com/api/v1/agents/agt_a1b2c3d4e5 \
  -H "Authorization: Bearer cfk_your_api_key"
const agentId = 'agt_a1b2c3d4e5';
const res = await fetch(`https://chatforge.aiedge247.com/api/v1/agents/${agentId}`, {
  method: 'DELETE',
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const result = await res.json();
console.log(result);
import requests

agent_id = 'agt_a1b2c3d4e5'
res = requests.delete(
    f'https://chatforge.aiedge247.com/api/v1/agents/{agent_id}',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())
Response
{
  "id": "agt_a1b2c3d4e5",
  "status": "deactivated",
  "deactivated_at": "2026-03-26T12:00:00Z"
}

Bulk create agents

POST /agents/bulk

Creates multiple agents in a single request. Useful for agencies managing many client sites. Maximum 20 agents per request.

ParameterTypeDescription
agents REQUIREDobject[]Array of agent objects. Each object accepts the same fields as POST /agents.
curl -X POST https://chatforge.aiedge247.com/api/v1/agents/bulk \
  -H "Authorization: Bearer cfk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "agents": [
      { "name": "Client A - Sales", "greeting": "Hello!", "color": "#6366f1" },
      { "name": "Client B - Support", "greeting": "How can I help?", "color": "#10b981" },
      { "name": "Client C - Booking", "greeting": "Ready to schedule?", "color": "#d4af37" }
    ]
  }'
const res = await fetch('https://chatforge.aiedge247.com/api/v1/agents/bulk', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cfk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agents: [
      { name: 'Client A - Sales', greeting: 'Hello!', color: '#6366f1' },
      { name: 'Client B - Support', greeting: 'How can I help?', color: '#10b981' },
      { name: 'Client C - Booking', greeting: 'Ready to schedule?', color: '#d4af37' }
    ]
  })
});
const data = await res.json();
console.log(data);
import requests

res = requests.post(
    'https://chatforge.aiedge247.com/api/v1/agents/bulk',
    headers={
        'Authorization': 'Bearer cfk_your_api_key',
        'Content-Type': 'application/json'
    },
    json={
        'agents': [
            {'name': 'Client A - Sales', 'greeting': 'Hello!', 'color': '#6366f1'},
            {'name': 'Client B - Support', 'greeting': 'How can I help?', 'color': '#10b981'},
            {'name': 'Client C - Booking', 'greeting': 'Ready to schedule?', 'color': '#d4af37'}
        ]
    }
)
print(res.json())
Response
{
  "agents": [
    { "id": "agt_p1q2r3s4t5", "name": "Client A - Sales", "status": "active" },
    { "id": "agt_u6v7w8x9y0", "name": "Client B - Support", "status": "active" },
    { "id": "agt_z1a2b3c4d5", "name": "Client C - Booking", "status": "active" }
  ],
  "created": 3,
  "failed": 0
}

Conversations & Leads

Access conversation transcripts and captured lead information for your agents.

List conversations

GET /agents/:id/conversations

Returns a paginated list of conversations for a specific agent. Each conversation includes message history, visitor metadata, and lead capture status.

Query ParameterTypeDescription
sincestringISO 8601 timestamp. Only return conversations started after this time.
limitintegerNumber of results per page. Default: 25, max: 100.
offsetintegerNumber of results to skip for pagination. Default: 0.
curl "https://chatforge.aiedge247.com/api/v1/agents/agt_a1b2c3d4e5/conversations?since=2026-03-01T00:00:00Z&limit=10" \
  -H "Authorization: Bearer cfk_your_api_key"
const agentId = 'agt_a1b2c3d4e5';
const params = new URLSearchParams({
  since: '2026-03-01T00:00:00Z',
  limit: '10'
});
const res = await fetch(
  `https://chatforge.aiedge247.com/api/v1/agents/${agentId}/conversations?${params}`,
  { headers: { 'Authorization': 'Bearer cfk_your_api_key' } }
);
const data = await res.json();
console.log(data);
import requests

agent_id = 'agt_a1b2c3d4e5'
res = requests.get(
    f'https://chatforge.aiedge247.com/api/v1/agents/{agent_id}/conversations',
    headers={'Authorization': 'Bearer cfk_your_api_key'},
    params={'since': '2026-03-01T00:00:00Z', 'limit': 10}
)
print(res.json())
Response
{
  "conversations": [
    {
      "id": "conv_x1y2z3a4b5",
      "agent_id": "agt_a1b2c3d4e5",
      "visitor_id": "vis_m1n2o3p4q5",
      "status": "completed",
      "messages_count": 8,
      "lead_captured": true,
      "duration_seconds": 245,
      "page_url": "https://example.com/pricing",
      "messages": [
        { "role": "assistant", "content": "Hi! How can I help you today?", "timestamp": "2026-03-20T14:00:00Z" },
        { "role": "user", "content": "What are your pricing plans?", "timestamp": "2026-03-20T14:00:15Z" },
        { "role": "assistant", "content": "We have three plans starting at $49/mo...", "timestamp": "2026-03-20T14:00:16Z" }
      ],
      "started_at": "2026-03-20T14:00:00Z",
      "ended_at": "2026-03-20T14:04:05Z"
    }
  ],
  "total": 142,
  "limit": 10,
  "offset": 0
}

List leads

GET /agents/:id/leads

Returns a paginated list of leads captured by a specific agent. Leads are created when a visitor provides their contact information during a conversation.

Query ParameterTypeDescription
sincestringISO 8601 timestamp. Only return leads captured after this time.
limitintegerNumber of results per page. Default: 25, max: 100.
offsetintegerNumber of results to skip for pagination. Default: 0.
curl "https://chatforge.aiedge247.com/api/v1/agents/agt_a1b2c3d4e5/leads?limit=25" \
  -H "Authorization: Bearer cfk_your_api_key"
const agentId = 'agt_a1b2c3d4e5';
const res = await fetch(
  `https://chatforge.aiedge247.com/api/v1/agents/${agentId}/leads?limit=25`,
  { headers: { 'Authorization': 'Bearer cfk_your_api_key' } }
);
const data = await res.json();
console.log(data);
import requests

agent_id = 'agt_a1b2c3d4e5'
res = requests.get(
    f'https://chatforge.aiedge247.com/api/v1/agents/{agent_id}/leads',
    headers={'Authorization': 'Bearer cfk_your_api_key'},
    params={'limit': 25}
)
print(res.json())
Response
{
  "leads": [
    {
      "id": "lead_r1s2t3u4v5",
      "agent_id": "agt_a1b2c3d4e5",
      "conversation_id": "conv_x1y2z3a4b5",
      "name": "Jane Smith",
      "email": "jane@example.com",
      "phone": "+1-555-0123",
      "company": "Acme Corp",
      "message": "Interested in the Growth plan for our dental practice.",
      "page_url": "https://example.com/pricing",
      "captured_at": "2026-03-20T14:02:30Z"
    }
  ],
  "total": 38,
  "limit": 25,
  "offset": 0
}

Knowledge

Manage the knowledge base content that powers your agents' responses. Knowledge can be plain text, markdown, FAQ pairs, or structured product information.

Add knowledge

POST /agents/:id/knowledge

Appends new content to an agent's knowledge base. The agent will begin using this knowledge in conversations immediately.

ParameterTypeDescription
content REQUIREDstringThe knowledge content to add. Max 50,000 characters per request.
typestringContent type: text (default), faq, product, or markdown.
curl -X POST https://chatforge.aiedge247.com/api/v1/agents/agt_a1b2c3d4e5/knowledge \
  -H "Authorization: Bearer cfk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "## Pricing\n- Starter: $49/mo (1 agent, 500 conversations)\n- Growth: $99/mo (5 agents, 2000 conversations)\n- Scale: $249/mo (unlimited agents, unlimited conversations)",
    "type": "markdown"
  }'
const agentId = 'agt_a1b2c3d4e5';
const res = await fetch(`https://chatforge.aiedge247.com/api/v1/agents/${agentId}/knowledge`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cfk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    content: '## Pricing\n- Starter: $49/mo\n- Growth: $99/mo\n- Scale: $249/mo',
    type: 'markdown'
  })
});
const result = await res.json();
console.log(result);
import requests

agent_id = 'agt_a1b2c3d4e5'
res = requests.post(
    f'https://chatforge.aiedge247.com/api/v1/agents/{agent_id}/knowledge',
    headers={
        'Authorization': 'Bearer cfk_your_api_key',
        'Content-Type': 'application/json'
    },
    json={
        'content': '## Pricing\n- Starter: $49/mo\n- Growth: $99/mo\n- Scale: $249/mo',
        'type': 'markdown'
    }
)
print(res.json())
Response
{
  "agent_id": "agt_a1b2c3d4e5",
  "knowledge_entries": 4,
  "total_size_bytes": 28200,
  "added_at": "2026-03-26T12:30:00Z"
}

Bulk update knowledge

POST /knowledge/bulk

Adds the same knowledge content to multiple agents at once. Ideal for distributing shared company information (hours, policies, contact details) across all agents.

ParameterTypeDescription
content REQUIREDstringThe knowledge content to add to each agent. Max 50,000 characters.
agent_ids REQUIREDstring[]Array of agent IDs to receive this content. Max 50 agents.
typestringContent type: text (default), faq, product, or markdown.
curl -X POST https://chatforge.aiedge247.com/api/v1/knowledge/bulk \
  -H "Authorization: Bearer cfk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Business hours: Mon-Fri 8am-6pm MST. Phone: (555) 123-4567. Email: support@example.com",
    "agent_ids": ["agt_a1b2c3d4e5", "agt_f6g7h8i9j0", "agt_k1l2m3n4o5"],
    "type": "text"
  }'
const res = await fetch('https://chatforge.aiedge247.com/api/v1/knowledge/bulk', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cfk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    content: 'Business hours: Mon-Fri 8am-6pm MST. Phone: (555) 123-4567.',
    agent_ids: ['agt_a1b2c3d4e5', 'agt_f6g7h8i9j0', 'agt_k1l2m3n4o5'],
    type: 'text'
  })
});
const data = await res.json();
console.log(data);
import requests

res = requests.post(
    'https://chatforge.aiedge247.com/api/v1/knowledge/bulk',
    headers={
        'Authorization': 'Bearer cfk_your_api_key',
        'Content-Type': 'application/json'
    },
    json={
        'content': 'Business hours: Mon-Fri 8am-6pm MST. Phone: (555) 123-4567.',
        'agent_ids': ['agt_a1b2c3d4e5', 'agt_f6g7h8i9j0', 'agt_k1l2m3n4o5'],
        'type': 'text'
    }
)
print(res.json())
Response
{
  "updated": 3,
  "failed": 0,
  "results": [
    { "agent_id": "agt_a1b2c3d4e5", "status": "success" },
    { "agent_id": "agt_f6g7h8i9j0", "status": "success" },
    { "agent_id": "agt_k1l2m3n4o5", "status": "success" }
  ]
}

Analytics & Account

Account analytics

GET /analytics

Returns aggregate analytics for your entire account, including total conversations, leads captured, response times, and usage against plan limits.

curl https://chatforge.aiedge247.com/api/v1/analytics \
  -H "Authorization: Bearer cfk_your_api_key"
const res = await fetch('https://chatforge.aiedge247.com/api/v1/analytics', {
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const analytics = await res.json();
console.log(analytics);
import requests

res = requests.get(
    'https://chatforge.aiedge247.com/api/v1/analytics',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())
Response
{
  "period": "2026-03-01T00:00:00Z/2026-03-26T23:59:59Z",
  "agents_active": 4,
  "agents_limit": 10,
  "conversations": {
    "total": 1247,
    "this_month": 412,
    "today": 18,
    "limit": 5000
  },
  "leads": {
    "total": 189,
    "this_month": 67,
    "today": 3
  },
  "response_time": {
    "avg_ms": 1150,
    "p95_ms": 2400
  },
  "top_pages": [
    { "url": "https://example.com/pricing", "conversations": 89 },
    { "url": "https://example.com/", "conversations": 67 },
    { "url": "https://example.com/contact", "conversations": 42 }
  ]
}

API key info

GET /me

Returns information about the authenticated API key, including the associated account, plan, and permissions. Useful for verifying your key is working correctly.

curl https://chatforge.aiedge247.com/api/v1/me \
  -H "Authorization: Bearer cfk_your_api_key"
const res = await fetch('https://chatforge.aiedge247.com/api/v1/me', {
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const me = await res.json();
console.log(me);
import requests

res = requests.get(
    'https://chatforge.aiedge247.com/api/v1/me',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())
Response
{
  "account_id": "acc_q1w2e3r4t5",
  "email": "you@example.com",
  "plan": "growth",
  "key_prefix": "cfk_a1b2...x9y0",
  "key_name": "Production API Key",
  "created_at": "2026-03-01T10:00:00Z",
  "permissions": ["agents:read", "agents:write", "conversations:read", "leads:read", "analytics:read", "webhooks:manage"],
  "rate_limit": {
    "requests_per_minute": 1000,
    "remaining": 987
  }
}

Webhooks

Webhooks let you receive real-time notifications when events happen in your ChatForge account. Instead of polling the API, register a URL and we will POST event payloads to it as they occur.

List webhooks

GET /webhooks

Returns all registered webhook endpoints for your account.

curl https://chatforge.aiedge247.com/api/v1/webhooks \
  -H "Authorization: Bearer cfk_your_api_key"
const res = await fetch('https://chatforge.aiedge247.com/api/v1/webhooks', {
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const data = await res.json();
console.log(data);
import requests

res = requests.get(
    'https://chatforge.aiedge247.com/api/v1/webhooks',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())
Response
{
  "webhooks": [
    {
      "id": "wh_a1b2c3d4e5",
      "url": "https://yourapp.com/webhooks/chatforge",
      "agent_id": null,
      "events": ["lead.captured", "conversation.completed"],
      "status": "active",
      "created_at": "2026-03-15T10:00:00Z",
      "last_triggered_at": "2026-03-26T09:45:00Z",
      "success_rate": 0.98
    }
  ],
  "total": 1
}

Register webhook

POST /webhooks

Registers a new webhook endpoint. ChatForge will send a verification POST with a challenge field to your URL immediately; respond with the challenge value to confirm.

ParameterTypeDescription
url REQUIREDstringThe HTTPS endpoint URL to receive webhook events.
events REQUIREDstring[]Array of event types to subscribe to. See Webhook Events.
agent_idstringScope events to a specific agent. If omitted, receives events from all agents.
curl -X POST https://chatforge.aiedge247.com/api/v1/webhooks \
  -H "Authorization: Bearer cfk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/chatforge",
    "events": ["lead.captured", "conversation.completed"],
    "agent_id": "agt_a1b2c3d4e5"
  }'
const res = await fetch('https://chatforge.aiedge247.com/api/v1/webhooks', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cfk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    url: 'https://yourapp.com/webhooks/chatforge',
    events: ['lead.captured', 'conversation.completed'],
    agent_id: 'agt_a1b2c3d4e5'
  })
});
const webhook = await res.json();
console.log(webhook);
import requests

res = requests.post(
    'https://chatforge.aiedge247.com/api/v1/webhooks',
    headers={
        'Authorization': 'Bearer cfk_your_api_key',
        'Content-Type': 'application/json'
    },
    json={
        'url': 'https://yourapp.com/webhooks/chatforge',
        'events': ['lead.captured', 'conversation.completed'],
        'agent_id': 'agt_a1b2c3d4e5'
    }
)
print(res.json())
Response
{
  "id": "wh_f6g7h8i9j0",
  "url": "https://yourapp.com/webhooks/chatforge",
  "events": ["lead.captured", "conversation.completed"],
  "agent_id": "agt_a1b2c3d4e5",
  "status": "active",
  "secret": "whsec_k1l2m3n4o5p6q7r8s9t0",
  "created_at": "2026-03-26T13:00:00Z"
}

Webhook secret: Store the secret value securely. Use it to verify the X-ChatForge-Signature header on incoming webhook requests. The signature is computed as HMAC-SHA256(secret, request_body).

Delete webhook

DELETE /webhooks/:id

Permanently deletes a webhook endpoint. Events will no longer be sent to the URL. This action cannot be undone.

curl -X DELETE https://chatforge.aiedge247.com/api/v1/webhooks/wh_a1b2c3d4e5 \
  -H "Authorization: Bearer cfk_your_api_key"
const webhookId = 'wh_a1b2c3d4e5';
const res = await fetch(`https://chatforge.aiedge247.com/api/v1/webhooks/${webhookId}`, {
  method: 'DELETE',
  headers: { 'Authorization': 'Bearer cfk_your_api_key' }
});
const result = await res.json();
console.log(result);
import requests

webhook_id = 'wh_a1b2c3d4e5'
res = requests.delete(
    f'https://chatforge.aiedge247.com/api/v1/webhooks/{webhook_id}',
    headers={'Authorization': 'Bearer cfk_your_api_key'}
)
print(res.json())
Response
{
  "id": "wh_a1b2c3d4e5",
  "deleted": true
}

Webhook Events Reference

When an event occurs, ChatForge sends a POST request to your registered webhook URL with a JSON payload. All payloads share a common envelope:

{
  "id": "evt_unique_event_id",
  "type": "event.type",
  "created_at": "2026-03-26T14:00:00Z",
  "agent_id": "agt_a1b2c3d4e5",
  "data": { ... }
}

Verify webhook authenticity by computing HMAC-SHA256(webhook_secret, raw_request_body) and comparing it to the X-ChatForge-Signature header. Respond with a 2xx status within 10 seconds. Failed deliveries are retried up to 5 times with exponential backoff.

lead.captured

Fired when a visitor provides their contact information during a conversation.

{
  "id": "evt_lc_a1b2c3d4e5",
  "type": "lead.captured",
  "created_at": "2026-03-26T14:05:00Z",
  "agent_id": "agt_a1b2c3d4e5",
  "data": {
    "lead_id": "lead_r1s2t3u4v5",
    "conversation_id": "conv_x1y2z3a4b5",
    "name": "Jane Smith",
    "email": "jane@example.com",
    "phone": "+1-555-0123",
    "company": "Acme Corp",
    "message": "Interested in the Growth plan.",
    "page_url": "https://example.com/pricing"
  }
}

conversation.completed

Fired when a conversation ends (visitor closes the widget or 30 minutes of inactivity).

{
  "id": "evt_cc_f6g7h8i9j0",
  "type": "conversation.completed",
  "created_at": "2026-03-26T14:10:00Z",
  "agent_id": "agt_a1b2c3d4e5",
  "data": {
    "conversation_id": "conv_x1y2z3a4b5",
    "messages_count": 12,
    "duration_seconds": 340,
    "lead_captured": true,
    "lead_id": "lead_r1s2t3u4v5",
    "page_url": "https://example.com/pricing",
    "visitor_id": "vis_m1n2o3p4q5"
  }
}

agent.limit_reached

Fired when an agent reaches its monthly conversation limit. The agent will continue to respond but conversations will not be logged until the next billing cycle or a plan upgrade.

{
  "id": "evt_lr_k1l2m3n4o5",
  "type": "agent.limit_reached",
  "created_at": "2026-03-26T14:15:00Z",
  "agent_id": "agt_a1b2c3d4e5",
  "data": {
    "agent_name": "Sales Assistant",
    "conversations_used": 500,
    "conversations_limit": 500,
    "plan": "starter",
    "resets_at": "2026-04-01T00:00:00Z"
  }
}

agent.installed

Fired when an agent's embed code loads successfully on a new domain for the first time.

{
  "id": "evt_ai_p1q2r3s4t5",
  "type": "agent.installed",
  "created_at": "2026-03-26T14:20:00Z",
  "agent_id": "agt_a1b2c3d4e5",
  "data": {
    "agent_name": "Sales Assistant",
    "domain": "example.com",
    "page_url": "https://example.com/",
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."
  }
}

payment.received

Fired when a payment is successfully processed for your account. Useful for keeping external billing systems in sync.

{
  "id": "evt_pr_u6v7w8x9y0",
  "type": "payment.received",
  "created_at": "2026-03-26T14:25:00Z",
  "agent_id": null,
  "data": {
    "amount_cents": 9700,
    "currency": "usd",
    "plan": "starter",
    "period_start": "2026-03-26T00:00:00Z",
    "period_end": "2026-04-26T00:00:00Z",
    "invoice_url": "https://pay.stripe.com/invoice/inv_..."
  }
}