
Connecting other dialers (Mojo, RedX, BatchDialer, etc.) via Zapier
Closr has a generic dialer ingest endpoint that accepts a normalized call event from any source. If your dialer has a Zapier trigger (most do), you can bridge it to Closr without waiting for us to build a native integration. The Zap fires when your dialer logs a call, transforms the payload, and posts it to Closr — where it lands in the contact timeline alongside calls you make through Closr's built-in dialer.
Who this is for
- •**Mojo Dialer** — triple-line cold-call dialer. Has a Zapier trigger on "Call Logged."
- •**RedX** (Real Estate Data X) — expired/FSBO dialer. Zapier trigger on "Call Completed."
- •**BatchDialer** — newer triple-line dialer. Zapier app available.
- •**Vulcan7** — expired listing dialer.
- •**Espresso Agent** — premium expired/FSBO.
- •**PhoneBurner** — multi-industry power dialer.
- •**CallTools** and most other call-center dialers.
- •**Anything else with a Zapier app.** If your dialer can fire a Zap when a call completes, it can post to Closr.
If you're on **Quo** (formerly OpenPhone), use the dedicated Quo integration instead — it's HMAC-signed, no Zapier needed. See the "Connecting Quo" guide. The generic endpoint actively blocks `provider: "quo"` so unsigned events can't land in the Quo namespace.
What you'll need
- •A **team API key** from Closr (one of your team's keys; generate one in Settings → Integrations → Zapier).
- •A **Zapier account** (the free tier covers basic Zaps; paid tiers are needed for >100 calls/month on most plans).
- •Your dialer connected as a Zap source.
Generating your Closr team API key
- 1Settings → Integrations → click the **Zapier** tile (or the API keys section).
- 2Click **New API key**. Give it a label tied to the dialer (e.g. "Mojo dialer Zap") so you can revoke individually later.
- 3Closr generates and shows the full key **once**. Copy it now. After this screen, only the first 8 characters are stored for display — the rest is hashed.
Generate a separate key per Zap. If you ever want to disconnect one dialer without breaking another, revoke just that key.
Set up the Zap
- 1In Zapier, create a new Zap. **Trigger:** your dialer's "Call completed" / "Call logged" event (the exact label varies by dialer).
- 2Connect your dialer account when prompted. Send a test event so Zapier captures a sample payload — you'll need to map fields against it.
- 3**Action:** "Webhooks by Zapier" → "POST."
- 4**URL:** `https://getclosr.app/api/integrations/dialer/event`
- 5**Method:** `POST`. **Data Pass-Through:** off. **Data:** see field mapping below. **Wrap Request In Array:** off.
- 6**Headers:**
- •`x-api-key`: paste your Closr team API key from the previous section
- •`Content-Type`: `application/json`
Map the payload fields
Closr's generic endpoint expects a normalized JSON body. Map your dialer's fields to these keys:
- •`provider` (required) — short string identifying the source: `"mojo"`, `"redx"`, `"batch"`, `"vulcan7"`, `"phoneburner"`, etc. Pick a stable slug; it surfaces in the timeline chip and is part of the dedup key.
- •`externalCallId` (required) — the dialer's call ID. Used for idempotency, so re-deliveries don't create duplicate rows.
- •`direction` (required) — `"INBOUND"` or `"OUTBOUND"` (exact case).
- •`from` (required) — caller phone (E.164 preferred: `+14165550123`). For OUTBOUND, this is your dialer number; for INBOUND, it's the contact who called.
- •`to` (required) — recipient phone (E.164 preferred). For OUTBOUND, this is the contact you dialed.
- •`duration` (required) — call length in **seconds** as a number.
- •`status` (required) — provider-native status string (`"completed"`, `"voicemail"`, `"busy"`, etc. — pass through whatever your dialer uses).
- •`startedAt` (required) — ISO 8601 timestamp (`"2026-05-31T14:32:00Z"`).
- •`transcript` (optional) — full transcript text, if your dialer provides one.
- •`aiSummary` (optional) — short AI-generated summary. **If present, Closr fires `CALL_COMPLETED` automations on this call.** If absent, the call still lands but no automation triggers.
- •`nextSteps` (optional) — array of strings, each a follow-up action your dialer's AI extracted.
If your dialer's AI summary feature is on, map `aiSummary` from it. That's the single fire-site for the `CALL_COMPLETED` automation — without it, automations don't run for these calls. (We chose this design because Zapier-fed providers typically batch transcript + summary into a single payload, so the summary's presence is the right signal.)
Provider-specific tips
- •**Mojo:** the call-logged event includes a `Call_ID` field — map to `externalCallId`. Mojo timestamps are usually local — convert to ISO 8601 in Zapier with a Formatter step.
- •**RedX:** the dialer fires after a call ends; map their `call_uuid` to `externalCallId`. RedX duration arrives in milliseconds — divide by 1000 with Zapier Formatter to get seconds.
- •**BatchDialer:** has a clean webhook payload that almost matches Closr's format already. Their `id` → `externalCallId`, `started_at` → `startedAt`, `duration_seconds` → `duration`.
- •**Vulcan7 / Espresso:** may require a paid Zapier integration plan. The triggers vary; check their Zapier app for "Call Outcome Recorded" or similar.
- •**PhoneBurner:** rich payloads — also includes `recording_url`. You can store the URL in a custom field if you need it; the generic endpoint doesn't accept recording URLs (recordings are vendor-side for non-Quo).
Test the Zap end-to-end
- 1In Zapier, click **Test action**. Zapier sends your mapped payload as a POST to Closr.
- 2Expect a **200 OK** response with a body like `{ "status": "created", "callRecordId": "..." }`.
- 3Open `/app/contacts/<id>` for the contact whose phone matches the call. You should see a new call row with chip `CALL · <PROVIDER> · MmSSs`.
- 4If you mapped `aiSummary`, open Settings → Automations and verify any `CALL_COMPLETED` automation fired (execution log shows the event).
- 5Turn the Zap on. Future calls will sync automatically.
Troubleshooting
- •**401 Unauthorized.** Your API key is missing or wrong. Verify the `x-api-key` header is set (not the URL query) and the key is the full one Zapier never truncated.
- •**400 Bad Request** — "provider, externalCallId, direction required" — one of the required fields is missing from the payload. Re-check your field mapping.
- •**400** — "provider \"quo\" not accepted on this endpoint" — you tried to use `"quo"` as the provider slug. Use the native Quo integration instead; this endpoint rejects unsigned Quo writes by design.
- •**Call lands but isn't attached to a contact.** The phone number in your `to`/`from` doesn't match the contact's `Contact.phone` in Closr. Closr uses an exact-string match — `+14165550123` doesn't match `(416) 555-0123`. Normalize to E.164 in your Zap with a Formatter step.
- •**CALL_COMPLETED automation didn't fire.** Verify the `aiSummary` field is in your payload. The automation trigger is gated on summary presence, not on call completion alone (intentional — see the field-mapping tip above).
- •**Duplicates.** Closr dedupes on `(provider, externalCallId)`. If you're seeing duplicates, your dialer is sending different IDs for the same call (rare) — re-check the field mapping.
If your dialer doesn't have a Zapier app but does have a webhook output, you can point its webhook directly at `https://getclosr.app/api/integrations/dialer/event` with the `x-api-key` header. Same contract, no middleware.