Overview
Minari can automatically send call data to your own systems when a call is completed.
A webhook is a way for Minari to instantly notify another app when something happens. Instead of manually exporting data, Minari sends it automatically to wherever you want.
This allows you to:
trigger automations,
sync data to your CRM
or build custom integrations using tools like Zapier, n8n, Make, or your own backend.
Setting up your webhook
Go to Settings → Integrations
In the Webhook section, click Add
Enter your webhook URL (the endpoint that will receive the data)
Click Save
Once configured, Minari will generate a unique secret key for your webhook. You can view it by clicking Show Secret. Keep this secret safe, you'll need it to verify that incoming requests are genuinely from Minari.
Getting your webhook URL from Zapier
Log in to Zapier and click Create Zap
For the trigger, search for Webhooks by Zapier
Choose Catch Hook as the event, then click Continue
Leave "Pick off a Child Key" empty and click Continue
Copy the webhook URL that Zapier generates
Paste this URL in Minari's webhook settings
The steps are similar for n8n and Make, create a Webhook trigger node and copy the generated URL. For n8n, make sure to activate your workflow so the production URL works.
Testing your webhook
After setup, click Send test event to send a sample payload to your endpoint. This helps you verify everything is working before real calls come through.
Test events include a test: true field so you can identify them.
Webhook payload
When a call is completed, Minari sends a POST request to your URL with the following JSON payload:
{
"event": "call.completed",
"call": {
"ended_at": "2025-12-17T14:30:00.000Z",
"status": "connected",
"direction": "outgoing",
"duration_seconds": 180,
"from_number": "+33100000000",
"to_number": "+33600000000",
"recording_url": "https://app.minari.ai/api/webhook-assets/recording/550e8400-e29b-41d4-a716-446655440000?expires=1734567890&sig=abc123",
"transcript_url": "https://app.minari.ai/api/webhook-assets/transcript/550e8400-e29b-41d4-a716-446655440000?expires=1734567890&sig=abc123",
"summary": "Discussed pricing options. Prospect is interested but needs internal approval before moving forward. Follow-up scheduled for next week."
},
"prospect": {
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"company": "Acme Inc",
"job_title": "Software Engineer",
"crm_contact_id": "123",
"crm_company_id": "456"
},
"user": {
"name": "Jane Smith",
"email": "jane@yourcompany.com"
},
"list": {
"list_name: "Q1 Outbound Campaign",
"list_id": "123"
}
}
Field reference
Field | Description |
event | Always call.completed |
call.ended_at | When the call ended (ISO 8601 format) |
call.status | Call status: connected, no-answer, busy, voicemail, left-voicemail, missed, failed, canceled |
call.direction | incoming or outgoing |
call.duration_seconds | Call duration in seconds |
call.from_number | Caller phone number |
call.to_number | Recipient phone number |
call.recording_url | Signed URL to download the call recording (MP3). Valid for 24 hours. |
call.transcript_url | Signed URL to fetch the call transcript (JSON). Valid for 24 hours. |
call.summary | Summary of the call |
prospect | Prospect info (or null if unknown) |
user | Minari user who made/received the call |
list | List info |
Recording and transcript URLs
The recording_url and transcript_url are signed URLs that expire after 24 hours. These URLs allow you to:
Download the recording: returns an MP3 audio file
Fetch the transcript: returns a JSON object with the full conversation
If you need to store the recording or transcript permanently, download them within the 24-hour window and save them to your own storage.
Verifying webhook signatures
Every webhook request includes a signature in the X-Webhook-Signature header. We recommend verifying this signature to ensure the request is genuinely from Minari.
The signature is an HMAC-SHA256 hash of the request body, using your webhook secret as the key.
Node.js example
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return signature === expectedSignature;
}
// In your webhook handler:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const isValid = verifyWebhookSignature(req.body, signature, 'your-secret-key');
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the webhook...
console.log('Call completed:', req.body);
res.status(200).send('OK');
});
Tip for Zapier/n8n users: These platforms receive webhooks automatically. Just use the "Webhook" trigger and map the fields from the payload. Signature verification is optional but recommended for sensitive workflows. If needed, you can verify the X-Webhook-Signature header using a Code step.
Retry behavior
If your endpoint doesn't respond with a success status (2xx), Minari will automatically retry the delivery:
Attempt 1: Immediate
Attempt 2: After 1 second
Attempt 3: After 2 more seconds
Attempt 4: After 4 more seconds
After 3 failed retries, the delivery is marked as failed. You can see the delivery history in your webhook settings.
Tip: Make sure your endpoint responds within 10 seconds to avoid timeouts.
Troubleshooting
Webhook not receiving data
Verify your URL is publicly accessible (not localhost)
Check that your endpoint returns a 2xx status code
Look at the Recent deliveries section in your webhook settings for error details
Invalid signature errors
Make sure you're using the correct secret (click Show Secret to copy it)
Verify you're computing the signature on the raw JSON body, not a parsed/modified version
Recording or transcript URL returns 403
403 Access denied: The URL has expired (24-hour limit) or the signature is invalid