Skip to content

Webhooks API

Webhook endpoints are public (no authentication required) and are mounted under /api/webhooks. They are called by external services.

POST /api/webhooks/reversecontact

Receives profile change alerts from Reverse Contact for monitored LinkedIn profiles. Validates the subscriptionId against known people records, computes a diff against the previous snapshot, and stores the alert.

Body:

FieldTypeRequiredDescription
subscriptionIdstringYesReverse Contact subscription ID (must match a person’s alert_subscription_id)
data.personobjectNoUpdated profile data

Response: { ok: true }

Error responses:

  • 400 — Invalid JSON or missing subscriptionId
  • 404 — Unknown subscription ID

POST /api/webhooks/reversecontact/resolve

Receives async resolve results from Reverse Contact when an email-to-LinkedIn lookup completes. Updates the target entity (company, contact, or person) with the resolved LinkedIn URL and triggers full profile enrichment.

Query parameters:

ParamTypeDescription
typestringEntity type: company, contact, or person
idstringEntity ID to update

Body: Reverse Contact resolve payload containing data.linkedinUrl or data.linkedInUrl.

Behaviour by entity type:

  • company — Saves LinkedIn URL, fetches full company profile (description, logo, specialties), uploads logo to R2 if available.
  • contact — Saves LinkedIn URL, triggers LinkedIn profile enrichment, uploads profile picture to R2.
  • person — Saves LinkedIn URL, triggers LinkedIn profile enrichment.

Response: { ok: true }


POST /api/webhooks/twilio/message-status

Receives delivery status updates from Twilio for outbound messages. Validates the request using HMAC-SHA1 signature verification.

Headers:

HeaderDescription
X-Twilio-SignatureHMAC-SHA1 signature for request validation

Form body (from Twilio):

FieldDescription
MessageSidTwilio message SID
MessageStatusStatus: queued, sent, delivered, failed, etc.
ErrorCodeError code (if applicable)

Response: 204 No Content

Error responses:

  • 403 — Missing or invalid Twilio signature
  • 400 — Missing required fields
  • 500 — Twilio not configured

POST /api/webhooks/twilio/inbound

Receives inbound SMS and WhatsApp messages from contacts. Validates the Twilio signature, matches the sender’s phone number to a contact record, and stores the message.

Headers:

HeaderDescription
X-Twilio-SignatureHMAC-SHA1 signature for request validation

Form body (from Twilio):

FieldDescription
FromSender phone number (may include whatsapp: prefix)
ToRecipient phone number
BodyMessage text
MessageSidTwilio message SID
NumMediaNumber of media attachments
MediaUrl0First media URL (if present)

The sender is matched against contact_relationship_profiles.phone_number, contact_relationship_profiles.whatsapp_number, contacts.mobile, and contacts.phone.

Response: Empty TwiML response (<Response></Response>) — no auto-reply is sent.

Error: 403 if signature validation fails.