EnterChat

Integration guide

From an empty workspace to a scan you can act on, then into your own systems.

Setting up

  1. 1

    Connect your WhatsApp number

    Through Meta's WhatsApp Business Platform. The number has to be one that is not already registered to the WhatsApp app on a phone — if it is, you will need to migrate it, which Meta walks you through. Budget an afternoon for the business verification rather than ten minutes.

  2. 2

    Feed it what you already have

    Do not write a knowledge base from nothing. Export a year of WhatsApp chats, drop in the price list PDF, photograph the note stuck to the till. The assistant reads them, groups the questions into topics and shows you a map to correct — which is a very different job from authoring.

  3. 3

    Rehearse before anyone real arrives

    Play the customer yourself for ten minutes. You will find two or three answers you would never give, and correcting them there costs nothing. Finding them because a customer got one is the expensive version.

  4. 4

    Start with everything on draft

    Let it write and hold for the first week or two, and release intents one at a time as their accuracy earns it. Opening hours and location can go autonomous on day one; complaints should probably never.

Your first API call

Create a key in Settings, then confirm it works. Every endpoint on this deployment answers against sample data, so this returns real JSON immediately.

curl "https://api.enterchat.io/v1/overview" \
  -H "X-API-Key: ech_live_your_key_here"

Client examples

JavaScript

const res = await fetch("https://api.enterchat.io/v1/conversations?status=needs_human", {
  headers: { "X-API-Key": process.env.ENTERCHAT_KEY },
});
const { data } = await res.json();

// Conversations whose free 24-hour window closes within the hour — reply now or pay later.
const urgent = data.filter(
  (c) => new Date(c.windowExpiresAt) - Date.now() < 60 * 60 * 1000,
);
console.log(`${urgent.length} of ${data.length} are about to cost you a template`);

PHP

$ch = curl_init("https://api.enterchat.io/v1/gaps");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-API-Key: " . getenv("ENTERCHAT_KEY")]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$payload = json_decode(curl_exec($ch), true);
foreach ($payload["data"] as $gap) {
    echo $gap["askCount"] . "× " . $gap["question"]["en"] . "\n";
}

Python

import os, requests

r = requests.get(
    "https://api.enterchat.io/v1/autonomy",
    headers={"X-API-Key": os.environ["ENTERCHAT_KEY"]},
    timeout=10,
)
r.raise_for_status()

# Anything still held for review, and how close it is to earning its own voice.
for row in r.json()["data"]:
    if row["state"] != "auto":
        pct = round(row["accuracy"] / row["threshold"] * 100)
        print(f'{row["intent"]:18} {row["state"]:8} {pct}% of the way there')

Verifying webhooks

Compare the signature header against an HMAC of the raw request body. Compare in constant time — a naive string equality check leaks timing information.

import crypto from "node:crypto";

export function verify(rawBody, signatureHeader, secret) {
  const expected =
    "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");

  const a = Buffer.from(expected);
  const b = Buffer.from(signatureHeader ?? "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Rate limits and retries

600 requests per minute per key. Grid scans are far more expensive than reads and are additionally limited to 60 per day. A 429 response carries Retry-After in seconds; respect it rather than backing off on a fixed timer.