Base URL https://timdad.online/api/v1. Send Authorization: Bearer gr_live_…; create a key in Settings → API with only the scopes it needs (a key can expire). 120 requests a minute per key. Errors: { "error": { "code": "…", "message": "…" } } with 400 / 401 / 403 / 404 / 409 / 422 / 429.
A website form, landing page or another system. Upserts by phone: 201 when created, 200 when the number already exists. Ad fields (platform, campaign, ad, click ids, utm_*) credit the exact ad.
Three shapes. A template goes any time (creates the lead if new). Text and files go into the client's open conversation: on the official number only if the client wrote in the last 24 hours; QR numbers, Telegram and website chat any time — otherwise 409 window_closed (send a template). Files are fetched once from a public HTTPS link (no redirects, 20 MB).
Created and sent to WhatsApp for approval (submit: false keeps it a draft). Variables are {{1}}, {{2}}… with one example each. A media header is fetched from header.link (JPG/PNG 5 MB, MP4 16 MB, PDF 20 MB).
Valid once, until it expires; 5 tries per code. A wrong code: { valid: false, reason, attempts_left }.
Request
{
"phone": "0551234567",
"code": "4821"
}
Response
{
"valid": true
}
POST/api/v1/calls
Log a call · scope calls:write
Any phone system reports a finished call. It lands on the client's card; a missed incoming call alerts the owner. Idempotent per (source, external_id).
Add an HTTPS address in Settings → API and pick events. Each POST has a JSON body { id, event, created_at, data } and the headers X-Grouthna-Event, X-Grouthna-Timestamp and X-Grouthna-Signature: sha256=HMAC_SHA256(secret, `timestamp.body`). Check the signature and reject old timestamps. Failed deliveries are retried.
lead.created — a new lead
lead.stage_changed — a lead moved to another stage