Integrations

Incoming events

Tell AnswerStack when something changes on your side, such as a cancelled tour, with a signed request to your connection’s webhook URL.

Your CRM or calendar system can tell AnswerStack when a meeting booked through a connection is cancelled on your side. It posts a small JSON event to the connection's own webhook URL, signed so AnswerStack knows it came from you.

Get the secret and the URL#

  1. Open the connection

    In the admin app, go to Connections and find the connection the meetings were booked through.

  2. Make a signing secret

    Press Incoming events secret, then Make a secret. Copy the secret and the webhook URL. The secret is shown once; if it is lost, make a new one. Making a new one stops the previous one.

This secret is only for requests you send to AnswerStack. It is not your CRM's API key, and not the secret AnswerStack signs its own requests to you with.

Send an event#

http
POST /v1/webhooks/connections/conn_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE HTTP/1.1
Content-Type: application/json
X-AnswerStack-Signature: t=1758463200,v2=4f1c3d2b9a8e7f60512a4b3c6d7e8f901a2b3c4d5e6f708192a3b4c5d6e7f809

{"event":"booking.cancelled","data":{"confirmationId":"8812","cancelledAt":"2026-09-21T14:00:00Z"}}
EventdataWhat AnswerStack does
booking.cancelledconfirmationId: the ID your system gave the meeting. cancelledAt (optional): ISO timeMarks the meeting cancelled
Anything elseAnythingAccepts it (202) and records it, no more

AnswerStack answers 202 with {"received": true, "handled": true} when it changed something, and handled: false when there was nothing to change (for example, the meeting was already cancelled). Sending the same event twice is safe.

Sign the request#

The header is x-answerstack-signature with the value t=<time>,v2=<signature>:

  • t is the current time in whole seconds since 1970 (Unix time).
  • v2 is the lowercase hex HMAC-SHA256 of the time, a full stop, and the raw request body, byte for byte, keyed with your signing secret.

A request whose time is more than five minutes from AnswerStack's clock is refused, so a captured request cannot be replayed later. Keep your server's clock synchronised.

Node.js#

js
import crypto from 'node:crypto';

const SECRET = process.env.ANSWERSTACK_INBOUND_SECRET;

async function send(url, event) {
  const body = JSON.stringify(event);
  const t = Math.floor(Date.now() / 1000);
  const v2 = crypto.createHmac('sha256', SECRET).update(`${t}.${body}`).digest('hex');
  return fetch(url, {
    method: 'POST',
    headers: { 'content-type': 'application/json', 'x-answerstack-signature': `t=${t},v2=${v2}` },
    body,
  });
}

Shell#

bash
BODY='{"event":"booking.cancelled","data":{"confirmationId":"8812"}}'
T=$(date +%s)
SIG=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$ANSWERSTACK_INBOUND_SECRET" -hex | sed 's/^.* //')
curl -X POST "$WEBHOOK_URL" \
  -H 'content-type: application/json' \
  -H "x-answerstack-signature: t=$T,v2=$SIG" \
  --data "$BODY"

A request with a missing or wrong signature, or for a connection that does not exist, gets 401.

Moving from the old signature#

Before signing secrets, requests were signed with the bare hex HMAC-SHA256 of the body, keyed with the connection's own credential, in the same header. That still works while you move:

  1. Make a signing secret for the connection, as above.
  2. Change your system to send t=…,v2=… with the new secret.
  3. From the first request AnswerStack accepts with the new signature, it refuses the old one for that connection. The Incoming events secret dialog says when that happened.

Support for the old signature will end for every connection; the changelog will say when, well in advance.