EduChat API Documentation

v1.0.0

The EduChat REST API gives you programmatic access to your leads, conversations, analytics, and webhook management. Build custom integrations, sync data to your CRM, or create internal dashboards.

Base URL: https://app.educhat.de/api/v1

Authentication

All API v1 endpoints require a Bearer token in the Authorization header. API keys use the ec_ prefix and are available exclusively on the SCALE plan.

Important: The full API key is only shown once at creation time. Store it securely. If lost, deactivate the old key and create a new one.
Header Format
Authorization: Bearer ec_test_xxxxxxxxxxxx
How to get an API key
  1. Ensure your tenant is on the SCALE plan.
  2. Navigate to Settings > API Keys in the EduChat dashboard.
  3. Click "Create API Key" and give it a descriptive name.
  4. Copy the key immediately and store it in a secure location.

Rate Limits

Rate limits are enforced per API key using a sliding window of 60 seconds. When exceeded, the API returns 429 Too Many Requests with a Retry-After header.

PlanRequests / minuteAPI Access
STARTER30Not available
GROWTH60Not available
SCALE120Full access
Rate Limit Headers

Every response includes rate limit information:

HeaderDescription
X-RateLimit-LimitMax requests allowed in the window
X-RateLimit-RemainingRemaining requests in the current window
X-RateLimit-ResetSeconds until the window resets
Retry-AfterSeconds to wait before retrying (only on 429)

Pagination

List endpoints use cursor-free page-based pagination. Pass page and limit as query parameters. The response includes a pagination object.

{
  "data": [...],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "totalPages": 3
  }
}
ParameterTypeDefaultDescription
pageinteger1Page number (1-based)
limitinteger20Items per page (1-100)

Leads

Access leads captured by the chatbot. Leads are scored 0-100 and categorized into tiers: COLD (<50), WARM (50-79), HOT (80+).

GET/api/v1/leadsList leads

Returns a paginated list of leads captured by the chatbot, ordered by creation date (newest first).

Parameters

NameInTypeRequiredDescription
pagequeryintegerNoPage number(default: 1)
limitqueryintegerNoItems per page (max 100)(default: 20)

Example Request

curl -X GET "https://app.educhat.de/api/v1/leads?page=1&limit=20" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": [
    {
      "id": "clx1abc2d0001ab12example",
      "name": "Max Mustermann",
      "phoneNumber": "+4915112345678",
      "email": "max@example.de",
      "courseInterest": "Weiterbildung IT",
      "score": 85,
      "tier": "HOT",
      "createdAt": "2026-02-28T14:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "totalPages": 3
  }
}

Conversations

Access chatbot conversations across all channels (WEB, WHATSAPP, EMBED).

GET/api/v1/conversationsList conversations

Returns a paginated list of conversations, ordered by creation date (newest first). Each entry includes a message count.

Parameters

NameInTypeRequiredDescription
pagequeryintegerNoPage number(default: 1)
limitqueryintegerNoItems per page (max 100)(default: 20)

Example Request

curl -X GET "https://app.educhat.de/api/v1/conversations?page=1&limit=20" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": [
    {
      "id": "clx1abc2d0002ab12example",
      "channel": "WHATSAPP",
      "status": "ACTIVE",
      "messageCount": 12,
      "createdAt": "2026-02-28T14:00:00.000Z",
      "updatedAt": "2026-02-28T14:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 156,
    "totalPages": 8
  }
}

Bot Configuration

Retrieve your chatbot's current personality, greeting text, and configuration.

GET/api/v1/bot-configGet bot configuration

Returns the current bot configuration including name, institution, greeting, tone, and persona.

Example Request

curl -X GET "https://app.educhat.de/api/v1/bot-config" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": {
    "id": "clx1abc2d0003ab12example",
    "botName": "StudyBot",
    "institutionName": "Bildungszentrum Musterstadt",
    "greetingText": "Hallo! Ich bin StudyBot, der KI-Assistent des Bildungszentrums Musterstadt.",
    "tone": "professional",
    "persona": "friendly_expert",
    "createdAt": "2026-01-15T10:00:00.000Z",
    "updatedAt": "2026-02-20T16:45:00.000Z"
  }
}

Tenant Readiness

The readiness score (0-100) indicates how prepared your tenant is to go live. It is calculated from 5 weighted dimensions and is capped at 70 until you receive your first HOT lead.

GET/api/v1/tenant/readinessGet readiness score

Returns the tenant's go-live readiness score with a breakdown of all 5 dimensions: bot configured (25%), knowledge base (20%), HubSpot connected (25%), first conversation (15%), and first HOT lead (15%).

Example Request

curl -X GET "https://app.educhat.de/api/v1/tenant/readiness" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": {
    "score": 70,
    "cappedAt70": true,
    "dimensions": {
      "botConfigured": {
        "label": "Bot konfiguriert",
        "description": "System-Prompt und Bot-Persönlichkeit eingerichtet",
        "weight": 25,
        "met": true,
        "actionPath": "/bot-einrichten"
      },
      "knowledgeBase": {
        "label": "Wissensdatenbank",
        "weight": 20,
        "met": true
      },
      "hubspotConnected": {
        "label": "HubSpot verbunden",
        "weight": 25,
        "met": true
      },
      "firstConversation": {
        "label": "Erstes Gespräch",
        "weight": 15,
        "met": true
      },
      "firstHotLead": {
        "label": "Erster HOT-Lead",
        "weight": 15,
        "met": false
      }
    }
  }
}

Analytics

Access aggregate analytics and the conversion funnel. Use the period parameter to specify the time window: 7d, 30d, or 90d.

GET/api/v1/analytics/overviewGet analytics overview

Returns aggregate analytics for the specified time period: total conversations, total leads, HOT leads, and average messages per conversation.

Parameters

NameInTypeRequiredDescription
periodquerystringNoTime period: 7d, 30d, or 90d(default: 30d)

Example Request

curl -X GET "https://app.educhat.de/api/v1/analytics/overview?period=30d" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": {
    "totalConversations": 156,
    "totalLeads": 42,
    "hotLeads": 8,
    "avgMessagesPerConversation": 7.3
  },
  "period": "30d"
}
GET/api/v1/analytics/funnelGet conversion funnel

Returns the conversion funnel: conversations -> leads -> HOT leads -> handoffs, with counts and conversion rates for each stage.

Parameters

NameInTypeRequiredDescription
periodquerystringNoTime period: 7d, 30d, or 90d(default: 30d)

Example Request

curl -X GET "https://app.educhat.de/api/v1/analytics/funnel?period=30d" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": {
    "stages": [
      { "name": "conversations", "count": 156, "conversionRate": 100 },
      { "name": "leads", "count": 42, "conversionRate": 26.92 },
      { "name": "hotLeads", "count": 8, "conversionRate": 19.05 },
      { "name": "handoffs", "count": 3, "conversionRate": 37.5 }
    ]
  },
  "period": "30d"
}

API Key Management

Note: API key management endpoints use session-based authentication (dashboard login), not API key auth. These are called from the EduChat dashboard UI. Requires the ADMIN or OWNER role.
GET/api/v1/keysList API keys (masked)

Returns all API keys for the tenant. Keys are masked — only the last 8 characters are visible. Requires ADMIN or OWNER role.

Example Request

curl -X GET "https://app.educhat.de/api/v1/keys" \
  -H "Cookie: sb-access-token=your_session_token"

Example Response 200 OK

{
  "data": [
    {
      "id": "clx1abc2d0010ab12example",
      "name": "Production Key",
      "key": "ec_************************a1b2c3d4",
      "lastUsed": "2026-02-28T14:30:00.000Z",
      "isActive": true,
      "createdAt": "2026-01-15T10:00:00.000Z"
    }
  ]
}
POST/api/v1/keysCreate an API key

Creates a new API key with the given name. The full key is only returned once — store it securely. Requires SCALE plan and ADMIN/OWNER role.

Request Body

{
  "name": "Production Integration"
}

Example Request

curl -X POST "https://app.educhat.de/api/v1/keys" \
  -H "Cookie: sb-access-token=your_session_token" \
  -H "Content-Type: application/json" \
  -d '{"name": "Production Integration"}'

Example Response 201 Created 200 OK

{
  "data": {
    "id": "clx1abc2d0010ab12example",
    "name": "Production Integration",
    "key": "ec_test_xxxxxxxxxxxx...",
    "createdAt": "2026-02-28T14:30:00.000Z"
  }
}
DELETE/api/v1/keys?id={keyId}Deactivate an API key

Soft-deletes (deactivates) an API key. The key can no longer be used for authentication. Requires ADMIN/OWNER role.

Parameters

NameInTypeRequiredDescription
idquerystringYesThe ID of the API key to deactivate

Example Request

curl -X DELETE "https://app.educhat.de/api/v1/keys?id=clx1abc2d0010ab12example" \
  -H "Cookie: sb-access-token=your_session_token"

Example Response 200 OK

{
  "success": true
}

Webhooks

Configure webhook endpoints to receive real-time notifications when events occur in your EduChat tenant. Webhooks are delivered as HTTP POST requests with HMAC-SHA256 signatures.

GET/api/v1/webhooksList webhook endpoints

Returns a paginated list of active webhook endpoints for the tenant.

Parameters

NameInTypeRequiredDescription
pagequeryintegerNoPage number(default: 1)
limitqueryintegerNoItems per page (max 100)(default: 20)

Example Request

curl -X GET "https://app.educhat.de/api/v1/webhooks" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": [
    {
      "id": "clx1abc2d0020ab12example",
      "name": "CRM Integration",
      "url": "https://example.de/webhooks/educhat",
      "events": ["lead.created", "lead.tier_changed"],
      "isActive": true,
      "createdAt": "2026-02-15T10:00:00.000Z",
      "updatedAt": "2026-02-15T10:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 2,
    "totalPages": 1
  }
}
POST/api/v1/webhooksCreate a webhook endpoint

Creates a new webhook endpoint. A signing secret is generated and returned in the response — store it securely for signature verification. The secret is only visible once.

Request Body

{
  "url": "https://example.de/webhooks/educhat",
  "events": ["lead.created", "lead.tier_changed"],
  "name": "CRM Integration"
}

Example Request

curl -X POST "https://app.educhat.de/api/v1/webhooks" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.de/webhooks/educhat",
    "events": ["lead.created", "lead.tier_changed"],
    "name": "CRM Integration"
  }'

Example Response 201 Created 200 OK

{
  "data": {
    "id": "clx1abc2d0020ab12example",
    "name": "CRM Integration",
    "url": "https://example.de/webhooks/educhat",
    "events": ["lead.created", "lead.tier_changed"],
    "secret": "whsec_test_xxxxxxxxxxxx...",
    "isActive": true,
    "createdAt": "2026-02-28T14:30:00.000Z"
  }
}
GET/api/v1/webhooks/{id}Get a webhook endpoint

Returns a single webhook endpoint by ID.

Parameters

NameInTypeRequiredDescription
idpathstringYesWebhook endpoint ID

Example Request

curl -X GET "https://app.educhat.de/api/v1/webhooks/clx1abc2d0020ab12example" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": {
    "id": "clx1abc2d0020ab12example",
    "name": "CRM Integration",
    "url": "https://example.de/webhooks/educhat",
    "events": ["lead.created", "lead.tier_changed"],
    "isActive": true,
    "createdAt": "2026-02-15T10:00:00.000Z",
    "updatedAt": "2026-02-15T10:00:00.000Z"
  }
}
DELETE/api/v1/webhooks/{id}Delete a webhook endpoint

Soft-deletes a webhook endpoint (sets isActive to false). It will no longer receive events.

Parameters

NameInTypeRequiredDescription
idpathstringYesWebhook endpoint ID

Example Request

curl -X DELETE "https://app.educhat.de/api/v1/webhooks/clx1abc2d0020ab12example" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "success": true
}
GET/api/v1/webhooks/{id}/deliveriesList webhook deliveries

Returns a paginated list of delivery attempts for a specific webhook endpoint, ordered by date (newest first). Useful for debugging failed deliveries.

Parameters

NameInTypeRequiredDescription
idpathstringYesWebhook endpoint ID
pagequeryintegerNoPage number(default: 1)
limitqueryintegerNoItems per page (max 100)(default: 20)

Example Request

curl -X GET "https://app.educhat.de/api/v1/webhooks/clx1abc2d0020ab12example/deliveries" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": [
    {
      "id": "clx1abc2d0030ab12example",
      "event": "lead.created",
      "statusCode": 200,
      "response": "{\"ok\":true}",
      "success": true,
      "attempts": 1,
      "createdAt": "2026-02-28T14:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 15,
    "totalPages": 1
  }
}
POST/api/v1/webhooks/{id}/testSend a test ping

Sends a test.ping event to the specified webhook endpoint and returns the result synchronously. Use this to verify your endpoint is correctly configured.

Parameters

NameInTypeRequiredDescription
idpathstringYesWebhook endpoint ID

Example Request

curl -X POST "https://app.educhat.de/api/v1/webhooks/clx1abc2d0020ab12example/test" \
  -H "Authorization: Bearer ec_test_xxxxxxxxxxxx"

Example Response 200 OK

{
  "data": {
    "success": true,
    "statusCode": 200,
    "response": "{\"ok\":true}"
  }
}

Webhook Events & Payloads

Webhooks are delivered as HTTP POST requests with the following envelope format:

{
  "event": "lead.created",
  "timestamp": "2026-02-28T14:30:00.000Z",
  "tenant_id": "clx1abc...",
  "data": { ... }
}
Available Events
EventDescriptionData Fields
lead.createdA new lead was capturedid, name, email, phoneNumber, courseInterest, score, tier
lead.updatedAn existing lead was updatedid, name, email, phoneNumber, courseInterest, score, tier
lead.tier_changedA lead's tier changed (e.g. WARM to HOT)id, previousTier, newTier, score
conversation.completedA conversation was completedid, channel, messageCount, leadId
handoff.requestedA sales handoff was triggeredconversationId, leadId, reason, assignedToUserId
Signature Verification

Every webhook delivery includes an X-EduChat-Signature header containing an HMAC-SHA256 signature of the request body, signed with your endpoint's secret. Always verify the signature before processing.

The X-EduChat-Event header contains the event type for routing convenience.

// Node.js signature verification example
const crypto = require("crypto");

function verifyWebhookSignature(body, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body)
    .digest("hex");

  const received = signature.replace("sha256=", "");

  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(received, "hex")
  );
}

// In your webhook handler:
app.post("/webhooks/educhat", (req, res) => {
  const signature = req.headers["x-educhat-signature"];
  const event = req.headers["x-educhat-event"];
  const rawBody = JSON.stringify(req.body);

  if (!verifyWebhookSignature(rawBody, signature, WEBHOOK_SECRET)) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  // Process the event
  const { event: eventType, data } = req.body;
  console.log(`Received ${eventType}:`, data);

  res.status(200).json({ ok: true });
});
Delivery details:
  • Timeout: 10 seconds — your endpoint must respond within this window.
  • Expected response: 2xx status code to confirm receipt.
  • Failed deliveries are logged and visible via the deliveries endpoint.
  • Use the test endpoint to verify your setup before going live.

Error Reference

All error responses follow a consistent format:

{
  "error": "Human-readable error message",
  "details": [...]  // Optional: Zod validation issues
}
StatusMeaningCommon Causes
400Bad RequestInvalid query parameters, malformed request body, missing required fields. Check the details array for specific validation errors.
401UnauthorizedMissing Authorization header, invalid API key, deactivated key, or key belongs to a non-SCALE tenant.
403ForbiddenInsufficient role permissions (e.g. MEMBER trying to manage API keys, which requires ADMIN or OWNER).
404Not FoundRequested resource does not exist or does not belong to your tenant.
429Too Many RequestsRate limit exceeded. Check the Retry-After header for the wait time in seconds.
500Internal Server ErrorUnexpected server error. These are logged automatically. If persistent, contact support.