Partner Integration Guide
This guide is for platforms integrating Tadhkir into their own systems — for example a university Student Information System (SIS) using Tadhkir to reach students on WhatsApp. It covers the two directions of the integration: you calling us (sending messages via the API) and us calling you (signed callbacks when a student responds).
If you only need to send reminders, see the Partner API reference. This guide focuses on the interactive, two-way flows (attendance check-ins, tuition payments, escalations).
Overview
Your system ──POST /v1/events──▶ Tadhkir ──WhatsApp──▶ Student
▲ │
│ student taps / pays
└──────── signed callback (webhook) ◀──────────────────────┘
- You send an event to Tadhkir's API (e.g. an attendance check-in or a tuition payment card).
- Tadhkir delivers an interactive WhatsApp message to the student.
- When the student responds (taps a button, pays), Tadhkir calls your webhook back with a signed payload so you can update your system.
1. Authentication
All API calls use your API key as a Bearer token:
Authorization: Bearer ta_live_xxxxxxxxxxxx
Use your test key (ta_test_…) during development — test-key traffic is routed through a sandbox and never sends a real WhatsApp message or takes a real payment.
2. Sending events
POST https://tadhkirapp.com/api/v1/events
The interactive university events:
Attendance check-in
{
"event": "attendance.missed",
"vertical": "university",
"idempotency_key": "checkin-2026-01-14-T2024-8821",
"customer": { "phone": "+447700900000", "name": "Tariq", "language": "en" },
"data": {
"student_id": "T2024-8821",
"window_closes": "2026-01-14T20:00:00Z",
"sponsor_ref": "LS/UKVI/2024",
"emergency_contact_phone": "+447700900111"
}
}
Sends an interactive check-in card with Confirm on campus / Log a reason buttons. If the student does not respond by window_closes (or escalate_at, if you provide it), Tadhkir escalates to emergency_contact_phone and sends you an attendance.escalated callback.
Tuition payment card
{
"event": "tuition.overdue",
"vertical": "university",
"idempotency_key": "tuition-FEE-2024-2-AMK",
"customer": { "phone": "+447700900000", "name": "Amara", "language": "en" },
"data": {
"student_id": "L2024-3341",
"amount": 420000,
"amount_display": "£4,200",
"currency": "gbp",
"gateway": "stripe"
}
}
amountis in minor units (pence/cents).amount_displayis the human string shown in the message.gatewayisstripeorflywire.- The response includes a
pay_url. On successful payment, Tadhkir sends the student a receipt and sends you apayment.settledcallback.
Idempotency: always send a unique idempotency_key. Re-sending the same key returns the original result instead of sending twice.
3. Receiving callbacks (webhooks)
Give us a callback URL and we generate a shared callback secret for you at onboarding. We POST a JSON event to your URL whenever a student responds.
Headers
| Header | Value |
|---|---|
Content-Type |
application/json |
X-Tadhkir-Event |
the event type (e.g. attendance.checkin) |
X-Tadhkir-Signature |
sha256=<hex> — HMAC-SHA256 of the raw body, keyed by your callback secret |
Callback payloads
Attendance check-in response
{
"type": "attendance.checkin",
"event_id": "…",
"student_ref": "T2024-8821",
"response": "on_campus", // or "off_campus"
"occurred_at": "2026-01-14T09:16:00Z"
}
Payment settled
{
"type": "payment.settled",
"event_id": "…",
"student_ref": "L2024-3341",
"reference": "cs_test_…",
"amount": "420000",
"occurred_at": "2026-01-14T10:19:00Z"
}
Attendance escalated (no response before the window closed)
{
"type": "attendance.escalated",
"event_id": "…",
"student_ref": "T2024-8821",
"occurred_at": "2026-01-14T20:05:00Z"
}
Verifying the signature (required)
Compute the HMAC-SHA256 of the raw request body using your callback secret, and compare it (constant-time) to the X-Tadhkir-Signature header. Reject the request if it doesn't match.
Node.js
import { createHmac, timingSafeEqual } from "crypto";
function verify(rawBody, header, secret) {
const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(header || "");
const b = Buffer.from(expected);
return a.length === b.length && timingSafeEqual(a, b);
}
Python
import hmac, hashlib
def verify(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header or "")
Verify against the exact bytes you received, before any JSON parsing/reserialization — re-encoding can change the body and break the signature.
Responding
Return 2xx quickly to acknowledge. We retry once on a network error or 5xx; a 4xx is treated as permanent (we won't retry). Callbacks are best-effort and never block message delivery.
4. MCP (for AI agents)
If you run an AI agent (e.g. a student-services assistant), Tadhkir exposes an MCP server so the agent can reach students directly:
POST https://tadhkirapp.com/api/v1/mcp — JSON-RPC 2.0, authenticated with your API key.
Tools: send_compliance_checkin, send_payment_card, send_timetable_card, send_enrollment_status. Call tools/list for their input schemas.
5. Going live checklist
- Test everything with your
ta_test_key first. - Give us your callback URL; store the callback secret we return.
- Implement signature verification (section 3) and return
2xx. - Map our callback payloads onto your SIS records.
- Switch to your
ta_live_key.
Questions: [email protected]