Headers
| Header | Value |
|---|---|
X-ConnectAI-Key | Your key ID |
X-ConnectAI-Timestamp | Unix time in SECONDS at the moment you sign |
X-ConnectAI-Signature | v1= followed by the hex HMAC (below) |
X-ConnectAI-Event-Id | A UUID you generate. Your idempotency key — optional but strongly recommended |
Idempotency-Key | Accepted as an alias for the above |
Signature
signature = "v1=" + hex( HMAC_SHA256( inboundSecret, timestamp + "." + rawBody ) )The timestamp is part of the signed string, not just a header. That is what makes a captured request un-replayable once it falls outside the window.
rawBodyis the exact byte sequence you transmit. Do not re-serialise.- For a request with no body, sign the empty string.
- Compare signatures in constant time when you verify ours.
Timestamp window
A timestamp more than 300 seconds from our clock is rejected with 401 signature_invalid, in either direction. If you see these intermittently, check NTP on the signing machine before anything else.
Transport
- HTTPS only, TLS 1.2 or higher.
- Never put a key or secret in a query string — they end up in logs and proxies.
- An IP allowlist can be set on your key if you have fixed egress addresses. Ask when the key is issued.
Rotation
Secrets can be rotated without downtime. When the inbound secret is rotated, the previous one keeps working for seven days, so requests already queued on your side do not start failing mid-flight. Move to the new secret inside that window.
What we do not use
There is no OAuth flow, no per-user token and no JWT. This is server-to-server between two known systems, and an integration key is never a user session.