Integratie Gebruiksscenario
Store Call Records and Recordings in Your Own System Using Webhooks
Learn how to store call records and automatically download recordings into your own system the moment a call ends.
Overview
Hipcall keeps call detail records accessible through the dashboard and REST API, but many teams need to push that data into their own systems — a data warehouse, compliance archive, CRM, or custom analytics dashboard. Doing it in real time, the moment a call ends, is exactly what the call_hangup webhook is designed for.
This guide shows how to receive the call_hangup event, store the call record in your own database, and automatically download the call recording before the pre-signed URL expires.
How It Works
When a call ends, Hipcall sends a call_hangup webhook to your endpoint. Your server parses the payload, inserts the call record into a database, and — if a recording URL is present — downloads the audio file in the background before the pre-signed URL expires.
Architecture
flowchart TD
A[Call ends] --> B[Hipcall fires call_hangup webhook]
B --> C[Your server receives payload]
C --> D[Store CDR in database]
D --> E{record_url\npresent?}
E -- Yes --> F[Download recording\nin background]
E -- No --> G[Done]
F --> H[Save MP3 locally\nupdate record path]
Step 1: Create the Webhook in Hipcall
- Go to Account > Integrations in your Hipcall dashboard.
- Click Create New Integration and choose Webhook.
- Configure the webhook:
| Field | Value |
|---|---|
| Target URL | https://your-server.example.com/webhook/hipcall-cdr |
| Events | Call Hangup (call_hangup) |
| Method | POST |
Local development: Use ngrok to expose your local server. Run
ngrok http 5007and use the generated URL as your target.
Step 2: Receive the Webhook
Hipcall POSTs a JSON payload to your endpoint every time a call ends.
Example payload:
{
"event": "call_hangup",
"data": {
"uuid": "call_abc123",
"caller_number": "+442045205757",
"callee_number": "+441234567890",
"direction": "inbound",
"call_duration": 45,
"started_at": "2026-04-02T10:00:00Z",
"ended_at": "2026-04-02T10:00:45Z",
"record_url": "https://storage.example.com/recordings/call_abc123.mp3?token=...",
"hangup_by": "callee"
}
}
Key fields:
| Field | Description |
|---|---|
uuid | Unique call identifier — use this to deduplicate |
caller_number / callee_number | Parties on the call |
direction | inbound or outbound |
call_duration | Duration in seconds |
record_url | Pre-signed URL to the MP3 recording — expires after a short time |
hangup_by | Who ended the call (caller, callee, or system) |
Respond with HTTP 200 quickly — move any heavy processing to the background.
Step 3: Store the CDR
Always filter on event === "call_hangup" — your endpoint may receive other events in the future. Use uuid as the primary key to prevent duplicate records if the webhook is retried.
@app.route('/webhook/hipcall-cdr', methods=['POST'])
def receive_cdr():
payload = request.json
if payload.get('event') != 'call_hangup':
return jsonify({"status": "ignored"}), 200
data = payload.get('data', {})
uuid = data.get('uuid')
# Deduplicate — Hipcall may retry on timeout
if db.execute('SELECT 1 FROM cdrs WHERE uuid = ?', (uuid,)).fetchone():
return jsonify({"status": "exists"}), 200
db.execute('''
INSERT INTO cdrs
(uuid, caller_number, callee_number, direction,
duration, started_at, ended_at, record_url, hangup_by)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
uuid,
data.get('caller_number'), data.get('callee_number'),
data.get('direction'), data.get('call_duration'),
data.get('started_at'), data.get('ended_at'),
data.get('record_url'), data.get('hangup_by'),
))
db.commit()
return jsonify({"status": "success"}), 201
Step 4: Download the Recording
The record_url is a pre-signed URL — it expires shortly after the call ends. Download the file in a background thread so your webhook endpoint returns immediately.
Wait a few seconds before downloading: the recording is finalized and uploaded to storage right after hangup, and a small delay ensures the file is ready.
def download_recording(record_url, uuid):
time.sleep(10) # Wait for the file to be ready on storage
response = requests.get(record_url, stream=True, timeout=30)
if response.status_code == 200:
path = f"./data/records/{uuid}.mp3"
with open(path, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
db.execute(
'UPDATE cdrs SET local_record_path = ? WHERE uuid = ?',
(f"/api/records/{uuid}.mp3", uuid)
)
db.commit()
# Trigger in the webhook handler after inserting the CDR
record_url = data.get('record_url')
if record_url:
threading.Thread(
target=download_recording,
args=(record_url, uuid),
daemon=True
).start()
Tools Used
| Tool | Purpose |
|---|---|
| Webhooks | Receive call_hangup event when a call ends |
Next Steps
- Webhooks documentation — Subscribe to events, configure retry logic, verify signatures
- REST API authentication — Secure your endpoint with API keys or Basic Auth
- REST API — CDR endpoints — Pull historical call records on demand via the REST API
Vraag de Community
Heeft u vragen of wilt u uw integratie delen? Sluit u aan bij de discussie.
Tools en API's
Zes manieren om Hipcall uit te breiden en te integreren in uw systemen.
REST API
Toegang tot uw Hipcall-gegevens via programmeren. Beheer extensies, initieer gesprekken, haal gespreksregistraties op en meer via een RESTful HTTP API met OAuth 2.0 en API-sleutelauthenticatie.
Webhooks
Ontvang realtime HTTP-meldingen voor meer dan 13 soorten gebeurtenissen — inkomende gesprekken, beantwoorde gesprekken, ophangingen, voicemails en meer. Verstuur gespreksgegevens onmiddellijk naar elk systeem.
Webservice-gebaseerde Slimme Routering
Routeer inkomende gesprekken dynamisch met uw eigen bedrijfslogica. Hipcall roept uw webservice aan tijdens het overgaan en routeert het gesprek op basis van uw JSON-antwoord.
Snel Bellen
Activeer uitgaande gesprekken programmatisch. Initieer een gesprek van de extensie van een agent naar elk nummer via een enkele API-aanvraag — geweldig voor klik-om-te-bellen integraties.
Extern Beheer
Beheer uw Hipcall-account vanuit externe systemen. Voorzie gebruikers, update gespreksstromen en beheer instellingen zonder in te loggen op het dashboard.
Insight Card
Geef realtime beller-context weer op het scherm van de agent op het moment dat een gesprek verbindt. Stuur willekeurige gegevens — naam, bedrijf, accountsaldo — vanuit uw CRM of ERP via de API.