1. Get a key
Keys are issued by ConnectAI, per clinic. Ask your ConnectAI contact, or have the clinic ask, and you will receive three values: a key ID, an inbound secret and an outbound secret.
| Value | What it is for |
|---|---|
keyId | Public identifier. Sent on every request in X-ConnectAI-Key |
inboundSecret | You sign requests TO ConnectAI with this |
outboundSecret | You verify webhooks FROM ConnectAI with this |
One key covers one clinic. If you serve several clinics, you hold one key per clinic and call the same endpoints with each — there is no multi-clinic credential.
2. Sign a request
Every request carries a timestamp and an HMAC-SHA256 signature over the exact bytes of the body. Full detail in Authentication.
const crypto = require("crypto");
const body = JSON.stringify({ externalId: "HMS-PT-88213" });
const timestamp = Math.floor(Date.now() / 1000);
const signature =
"v1=" +
crypto.createHmac("sha256", INBOUND_SECRET)
.update(`${timestamp}.${body}`, "utf8")
.digest("hex");
await fetch("https://api-ec2.connectai.care/master/integration/v1/ping", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-ConnectAI-Key": KEY_ID,
"X-ConnectAI-Timestamp": String(timestamp),
"X-ConnectAI-Signature": signature,
},
body, // send the SAME string you signed
});import hashlib, hmac, json, time, requests
body = json.dumps({"externalId": "HMS-PT-88213"}, separators=(",", ":"))
timestamp = int(time.time())
signature = "v1=" + hmac.new(
INBOUND_SECRET.encode(),
f"{timestamp}.{body}".encode(),
hashlib.sha256,
).hexdigest()
requests.post(
"https://api-ec2.connectai.care/master/integration/v1/ping",
data=body, # send the SAME bytes you signed
headers={
"Content-Type": "application/json",
"X-ConnectAI-Key": KEY_ID,
"X-ConnectAI-Timestamp": str(timestamp),
"X-ConnectAI-Signature": signature,
},
)<?php
$body = json_encode(["externalId" => "HMS-PT-88213"]);
$timestamp = time();
$signature = "v1=" . hash_hmac("sha256", "{$timestamp}.{$body}", $inboundSecret);
$ch = curl_init("https://api-ec2.connectai.care/master/integration/v1/ping");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body, // the SAME string you signed
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-ConnectAI-Key: {$keyId}",
"X-ConnectAI-Timestamp: {$timestamp}",
"X-ConnectAI-Signature: {$signature}",
],
]);
curl_exec($ch);3. Confirm the handshake
A successful POST /ping proves your signature was accepted and shows which clinic the key is bound to.
{
"status": "ok",
"keyId": "cai_live_…3c06",
"environment": "live",
"clinic": {
"connectaiId": "68d63629fdec0a56e25e0a6d",
"name": "Sunrise Dental"
},
"serverTime": "2026-09-24T09:12:07.412Z"
}Compare serverTime against your own clock. A drift of more than five minutes will make every signed request fail, and this is the quickest way to spot it.
4. Next
- Read Authentication for the signature construction, rotation and timestamp rules.
- Read Webhooks before you point us at a URL — the response contract matters.
- Use the sandbox while you build. It never messages patients.