Skip to main content
Internal reference — not the public API

This documents NearSync's internal action-dispatch surface, used by the apps themselves and by tenant automations. It is not the public API and carries no stability guarantee — actions may change or be removed without notice. For the supported, versioned public API see API Reference.

Webhooks

NearSync exposes incoming webhook endpoints for receiving events from third-party services. These handlers use GET or non-JSON POST methods and bypass JWT authentication, relying instead on provider-specific verification mechanisms.

All webhook endpoints share the same base URL as the hyper-worker:

https://<project>.supabase.co/functions/v1/hyper-worker

WhatsApp Webhook Verification (GET)

Meta requires webhook URL verification before it will deliver messages. This GET endpoint handles the verification handshake.

Method: GET Auth: None (Meta verifies via token match)

Request

Meta sends a GET request with these query parameters:

GET /functions/v1/hyper-worker?hub.mode=subscribe&hub.verify_token=<your-verify-token>&hub.challenge=<challenge-string>
ParameterDescription
hub.modeAlways subscribe for webhook verification
hub.verify_tokenThe verify token you configured in the Meta app dashboard
hub.challengeA random string that must be echoed back to confirm ownership

Process

  1. Reads the stored WhatsApp verify token from organization settings
  2. Compares hub.verify_token against the stored value
  3. If they match, returns the hub.challenge value as plain text
  4. If they do not match, returns 403

Response

Success (200): The challenge string as plain text

Failure (403):

{
"error": "Invalid verify token"
}

Setup

To configure WhatsApp webhooks:

  1. Set your verify token in the NearSync system settings
  2. In the Meta App Dashboard, set the webhook URL to your hyper-worker URL
  3. Enter the same verify token
  4. Meta will send the verification GET request automatically

WhatsApp Incoming Messages (POST)

Receives incoming WhatsApp messages from the Meta webhook. Automatically creates or updates conversations in the CRM.

Method: POST Content-Type: application/json Auth: None (Meta webhook - signature verified externally by Meta)

Request

Meta delivers the standard WhatsApp Business API webhook payload:

{
"object": "whatsapp_business_account",
"entry": [
{
"changes": [
{
"value": {
"messages": [
{
"from": "1234567890",
"id": "wamid.xxx",
"timestamp": "1711000000",
"type": "text",
"text": { "body": "Hello, I need support" }
}
],
"contacts": [
{
"profile": { "name": "John Smith" },
"wa_id": "1234567890"
}
]
}
}
]
}
]
}

Process

  1. Extracts the message from the webhook payload
  2. Normalizes the sender's phone number
  3. Searches for an existing contact by phone number
  4. If no match is found: creates a new lead in the default CRM pipeline with round-robin admin assignment
  5. Inserts the message as a comment on the associated deal

Auto-Lead Creation

When a message arrives from an unknown number, the system automatically:

  • Creates a new contact record with the sender's phone and WhatsApp profile name
  • Creates a new deal in the default pipeline's first stage
  • Assigns it to an admin via round-robin
  • Tags the deal as type whatsapp

Response

{
"success": true
}

Twilio Voice Webhook (POST)

Handles incoming and outgoing voice calls via Twilio. Returns TwiML (Twilio Markup Language) XML instructions.

Method: POST Content-Type: application/x-www-form-urlencoded (not JSON) Auth: Twilio signature validation via X-Twilio-Signature header (not JWT)

Request

Twilio sends form-encoded data:

To=+1234567890&From=+1234567890&CallSid=CA...
FieldDescription
ToDestination phone number
FromCaller's phone number
CallSidUnique Twilio call identifier

Process

  1. Extracts the To number from the form data
  2. Returns TwiML XML with a <Dial> command to connect the call
  3. Twilio validates the request using the X-Twilio-Signature header against your auth token

Response

Content-Type: text/xml

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial>+1234567890</Dial>
</Response>

Signature Validation

Twilio signs every webhook request using your account's auth token. The hyper-worker validates the X-Twilio-Signature header to ensure the request genuinely originated from Twilio. Requests with invalid signatures are rejected with a 403 response.


Email Tracking Pixel (GET)

A 1x1 transparent GIF endpoint used for email open tracking. When an email recipient's client loads the image, the corresponding email is marked as read.

Method: GET Auth: None

Request

GET /functions/v1/hyper-worker?type=track-email&id=<tracking-uuid>
ParameterDescription
typeMust be track-email
idThe tracking UUID assigned when the email was sent (see send-email)

Process

  1. Looks up the tracking ID in the email_messages table
  2. Sets is_read = true on the matching record
  3. Returns a 1x1 transparent GIF with no-cache headers

Response

Content-Type: image/gif Cache-Control: no-cache, no-store, must-revalidate

Returns a 1x1 transparent GIF image (not JSON). The response includes no-cache headers to ensure the pixel loads on every email open.

How It Works

When you send an email with a trackingId via the send-email endpoint, a tracking pixel <img> tag is appended to the email body. The src attribute points to this endpoint with the tracking ID. When the recipient opens the email and their email client loads images, this endpoint fires, recording the open event.

Limitations

Email open tracking has inherent limitations. Some email clients block external images by default, pre-fetch images for caching, or load images in a privacy proxy. Treat open tracking data as directional rather than exact.


Error Handling

Webhook endpoints prioritize reliability over detailed error reporting, since the caller is a third-party service rather than a human user.

ScenarioBehavior
Invalid WhatsApp verify tokenReturns 403
Malformed WhatsApp payloadReturns 200 (acknowledged) with no processing
Invalid Twilio signatureReturns 403
Tracking ID not foundReturns the GIF anyway (silent failure)
Internal processing errorReturns 200 to prevent retries, logs error internally

Returning 200 on processing errors prevents third-party services from aggressively retrying failed deliveries and flooding the system with duplicate events.