Complete reference for all ChatbotSaaS API endpoints. The base URL is your app domain — e.g. https://yourapp.com.
Pass your sk_live_... key in the Authorization: Bearer header.
Pass ADMIN_SECRET in the Authorization: Bearer header.
Pass CRON_SECRET in the Authorization: Bearer header. Set by Vercel Cron.
/api/healthPublicedgeSystem health check. Returns KV connectivity, env-var status, and a ready_to_sell boolean. Missing env var names are only revealed to authenticated admins.
{ status, ready_to_sell, version, response_ms, checks: { kv, env_vars } }/api/chatAPI Keyedge20-step chat hot path. Injection detection → auth → domain check → rate limit → status/usage checks → FAQ cache → RAG → AI completion → tool calls (lead capture / escalation) → conversation save → analytics.
{ message: string, conversationId?: string, sessionId?: string, metadata?: { url, userAgent } }{ reply, conversationId, intent, sentiment, followUpQuestions, leadCaptured, escalated, model, usage }/api/demoPublicedgeLive demo endpoint (no API key). Supports 4 built-in business personas (SaaS, Ecommerce, Healthcare, Legal). Rate-limited to 30 req/min per IP.
{ message: string, business: "saas" | "ecommerce" | "healthcare" | "legal", conversationId?: string }{ reply, conversationId, followUpQuestions, business }/api/widget-tokenAPI KeynodeExchange a raw API key for a short-lived (1hr) widget token. Use this so the raw key is never embedded in HTML.
{}{ token: string, expiresAt: number }/api/widget-tokenPublicnodeResolve a widget token to a hashed key for server-side use.
{ hashedKey: string }/api/client/accountAPI KeynodeAccount overview including status, plan, trial end date, monthly usage, and lead/conversation counts.
{ client, usage, leadsCount, conversationsCount }/api/client/leadsAPI KeynodePaginated list of captured leads with name, email, phone, company, intent, and timestamp.
{ leads: Lead[], count: number }/api/client/conversationsAPI KeynodeLast 30 conversations with message history, intent, sentiment, and lead/escalation flags.
{ conversations: Conversation[] }/api/client/kbAPI KeynodeList knowledge base chunks for this client. Pro+ plan required.
{ chunks: string[], count: number }/api/client/kbAPI KeynodeAdd knowledge to the RAG vector index. Accepts a URL to scrape (up to 10 pages) or raw text. Pro+ plan required.
{ type: "url" | "text", content: string }{ chunks: number, message: string }/api/client/upgradeAPI KeynodeInitiate a PayPal subscription upgrade. Returns a PayPal approval URL to redirect the user to.
{ plan: "starter" | "pro" | "enterprise", billingPeriod: "monthly" | "annual" }{ approvalUrl: string, subscriptionId: string }/api/client/cancelAPI KeynodeCancel the active PayPal subscription. Requires { confirm: true } in body as a safety guard.
{ confirm: true }{ cancelled: true, status: "cancelled" }/api/billing/returnPublicnodePayPal return URL after user approves a subscription. Verifies the subscription_id matches the pending record stored for this client (prevents account takeover), then activates the account.
Redirect to /client-dashboard?upgrade=success or ?upgrade=error
/api/webhooks/paypalPublicnodePayPal webhook receiver. Verifies PAYPAL-TRANSMISSION-SIG and processes 11 event types (ACTIVATED, RENEWED, CANCELLED, EXPIRED, SUSPENDED, PAYMENT.SALE.*, PAYMENT.FAILED, UPDATED). Idempotent via NX KV set.
{ received: true }/api/webhooks/shopifyPublicnodeShopify webhook receiver. Verifies HMAC-SHA256 signature per client, stores last 100 events. Client identified by ?client= query param.
Shopify webhook payload
{ received: true }/api/admin/clientsAdminnodeList all clients with config, usage, and lead counts. Sensitive fields (hubspotApiKey, shopifyWebhookSecret) are redacted.
{ clients: ClientConfig[], count: number }/api/admin/clientsAdminnodeCreate a new client. Generates an API key (sk_live_... prefix), stores only the HMAC-SHA256 hash. The raw key is returned once and never stored.
{ businessName, email, domain, plan, module, widgetTitle?, widgetColor? }{ apiKey: string (returned once), hashedKey, client }/api/admin/clients/[hashedKey]AdminnodeGet a single client by hashed key.
ClientConfig (secrets redacted)
/api/admin/clients/[hashedKey]AdminnodeUpdate client config or run a special action: toggle_active, rotate_key (copies all KV data to new prefix), force_plan, extend_trial.
{ action?: "toggle_active"|"rotate_key"|"force_plan"|"extend_trial", ...fields }Varies by action
/api/admin/clients/[hashedKey]AdminnodeGDPR erasure. Cancels PayPal subscription, deletes vector KB, and removes all 30+ KV key patterns for this client.
{ deleted: true, hashedKey }/api/admin/analyticsAdminnodeAggregated analytics for a client over 30 or 90 days: totals, daily breakdown, top intents, top sentiments.
AggregatedAnalytics
/api/admin/billingAdminnodeBilling ledger for a client (last 50 events).
{ ledger: BillingEvent[] }/api/admin/billingAdminnodeForce a plan change on a client.
{ client: hashedKey, plan: PlanId }{ updated: true }/api/admin/broadcastAdminnodeSend a broadcast email to Active, Paid, Trial, or All clients. Supports {{business_name}} substitution and dry-run mode.
{ subject, body, audience: "active"|"paid"|"trial"|"all", dryRun?: boolean }{ queued: number, dryRun: boolean, recipients?: string[] }/api/admin/logsAdminnodeSearch logs. Type: audit (last 100 audit entries), errors (last 100 errors), gdpr_export (full JSON export for one client).
AuditEntry[] | ErrorEntry[] | GDPR JSON
/api/admin/leadsAdminnodeAll leads across all clients, or filtered to one client. Supports CSV export via ?format=csv.
{ leads: Lead[] } or CSV file/api/admin/kbAdminnodeList knowledge base chunks for a client.
{ chunks: string[], count: number }/api/admin/kbAdminnodeAdd knowledge (URL scrape up to 10 pages, or raw text) to a client's RAG vector index.
{ client: hashedKey, type: "url"|"text", content: string }{ chunks: number, message: string }/api/admin/kbAdminnodeDelete all knowledge base vectors for a client.
{ deleted: true }/api/cron/daily-syncCron SecretnodeRuns at 06:00 UTC daily. Scans all active clients: expires trials, repairs PayPal status drift, detects fast-cancel fraud (subscription cancelled < 48h after activation).
{ processed: number, errors: number }/api/cron/email-queueCron SecretnodeRuns hourly. Drains the email queue — up to 100 emails per run with a 1.1s delay between sends (Resend rate limit compliance). 3 retries per message.
{ sent: number, failed: number }/api/client/accountAPI KeynodeIncludes current-month usage count (hincrby per-day analytics), lead count, and conversation count.
{ client, usage, leadsCount, conversationsCount }/api/webhooks/paypalPublicnodePayPal sends webhook events here. Signature verified with PAYPAL_WEBHOOK_ID. Events processed: BILLING.SUBSCRIPTION.ACTIVATED/RENEWED/CANCELLED/EXPIRED/SUSPENDED/UPDATED, PAYMENT.SALE.COMPLETED/DENIED/REFUNDED, PAYMENT.FAILED.
PayPal webhook payload
{ received: true }/api/webhooks/shopifyPublicnodeShopify sends webhook events here. HMAC-SHA256 verified per client using shopifyWebhookSecret. Stores last 100 events per client.
Shopify webhook payload
{ received: true }All endpoints also share a global per-IP limit of 30 req/min. Rate-limited responses return HTTP 429 with a retryAfter timestamp.
| Status | Meaning | Example |
|---|---|---|
| 400 | Bad request / injection blocked | Invalid JSON, injection detected |
| 401 | Unauthorized | Missing or invalid API key |
| 402 | Payment required | Trial expired or subscription lapsed |
| 403 | Forbidden | Domain not on allowlist, account suspended |
| 404 | Not found | Client or resource does not exist |
| 429 | Rate limit / usage cap | Per-minute key limit, monthly chat cap |
| 500 | Server error | Unexpected error (check /api/health) |
| 503 | Service unavailable | AI or KV temporarily unavailable |