Skip to main content

Testing webhooks

Using the dashboard

Every connection page has a Send Test Event button, which sends a synthetic event through the same code path as a real webhook — the request never actually leaves Sprio to hit LeadSquared or Zoho, so it verifies your assistant assignment, owner-gate, and dedup logic without depending on either provider being reachable. This works identically for both LeadSquared and Zoho CRM connections, and is always the right first step — before touching a script or a real CRM record — since it isolates "is Sprio's own pipeline configured correctly" from "is the provider actually delivering events."

Testing LeadSquared

Because LeadSquared posts lead fields flat on the request body, you can simulate a realistic event directly, in whatever tooling you're comfortable with:

curl -X POST "https://api.voice-up.sprio.ai/api/webhooks/leadsquared/<connectionId>" \
-H "X-Sprio-Webhook-Token: <your connection's secret token>" \
-H "Content-Type: application/json" \
-d '{"Lead": {"FirstName": "Test", "Phone": "+91XXXXXXXXXX"}}'
ResponseMeaning
200 {"received": true}Token accepted, event queued for processing
401 {"error": "unauthorized"}Token header missing or doesn't match the connection's stored token — check the value on your connection's dashboard page
404 {"error": "unknown connection"}The connectionId in the URL doesn't exist

A 200 here only confirms the request was accepted — it doesn't mean a call was placed. Check Integrations → Activity to see the actual downstream outcome (owner-gate skip, dedup skip, or a real call queued).

Testing the owner-reassignment shape specifically

If you want to test owner-reassignment handling (not just lead-creation) directly, remember the payload must be wrapped, and your test owner ID must match trigger_owner_user_id on the connection:

curl -X POST "https://api.voice-up.sprio.ai/api/webhooks/leadsquared/<connectionId>" \
-H "X-Sprio-Webhook-Token: <your connection's secret token>" \
-H "Content-Type: application/json" \
-d '{
"Before": {"OwnerId": "old-owner-guid", "ProspectID": "test-123"},
"After": {"OwnerId": "your-trigger-owner-guid", "ProspectID": "test-123", "FirstName": "Test", "Phone": "+91XXXXXXXXXX"}
}'

Sending the fields flat (unwrapped) here will silently fail owner matching, since Sprio only reads payload.After for this event shape — if a test like this produces no call and no obvious error, this is the first thing to check.

Testing Zoho CRM

Zoho's real webhook payload carries only a record ID and a token — there's no equivalent flat request example that reflects reality, since Sprio always fetches the full lead from Zoho's own API rather than trusting the notification body. This makes direct request testing much less useful for Zoho than for LeadSquared. Instead:

  1. Start with Send Test Event on the connection page — this exercises the entire processing pipeline (owner-gate, dedup, assistant assignment) without touching Zoho at all, and is the fastest way to confirm everything downstream of "a notification arrived" is configured correctly.
  2. To test the real end-to-end path, create or reassign a lead in your actual Zoho CRM account and watch the connection's Activity tab. Zoho's notification delivery timing isn't instant or tightly bounded — give it a couple of minutes before concluding it didn't fire.
  3. If nothing arrives after a real change, check the connection's watch channel status before assuming the integration is broken — Zoho has, in practice, reported a channel as healthy while silently delivering nothing (see Integration: Zoho CRM). A dashboard's own "channel active" indicator isn't sufficient proof by itself; if this is suspected, ask Sprio support to check the independent health-check result for that channel.

If you do want to simulate a raw Zoho notification for pipeline testing (understanding that this bypasses Zoho's own API entirely and Sprio will still try to fetch the referenced lead ID for real):

curl -X POST "https://api.voice-up.sprio.ai/api/webhooks/zoho-crm/<connectionId>" \
-H "Content-Type: application/json" \
-d '{"token": "<your connection'"'"'s token>", "module": "Leads", "operation": "update", "ids": ["4876876000001234567"]}'

Use a real lead ID from your Zoho account for ids — Sprio will actually call Zoho's API to fetch it, so a made-up ID will fail lookup rather than producing a useful test.

Checking activity

Every webhook call (test or real) appears in Integrations → Activity for that connection, along with whether it triggered a call and why. Common outcomes you'll see there, and what they mean:

Activity outcomeMeaning
call queuedA real call was placed
owner_mismatchReceived and valid, but the lead's owner didn't match trigger_owner_user_id — expected behavior, not an error
phone_already_calledCross-assistant dedup blocked a repeat dial to this number
already_called / already_called_raceThis exact lead already triggered a call earlier today
auto_call_disabledThe connection received the event but auto-calling is toggled off
no_dialable_phoneNo usable phone number was found in the payload or the fetched record
no_lead_id_in_payloadSprio couldn't find a lead identifier field at all — often means a source-side field naming change; the raw payload keys are logged alongside this for diagnosis

This is the authoritative place to check outcomes — a webhook can be received and acknowledged (200) but still be legitimately skipped downstream, which won't show up as an error in the source CRM's own delivery logs. If a client reports "nothing happened," start here before assuming a bug.