Caso de Uso de Integración
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
Preguntar a la Comunidad
¿Tienes preguntas o quieres compartir tu integración? Únete a la discusión.
Herramientas y APIs
Seis formas de extender e integrar Hipcall en tus sistemas.
REST API
Accede a tus datos de Hipcall de forma programática. Gestiona extensiones, inicia llamadas, recupera registros de llamadas y más a través de una API HTTP RESTful con autenticación OAuth 2.0 y clave API.
Webhooks
Recibe notificaciones HTTP en tiempo real para más de 13 tipos de eventos: llamadas entrantes, llamadas contestadas, colgadas, buzones de voz y más. Envía datos de llamadas a cualquier sistema al instante.
Enrutamiento Inteligente Basado en Servicio Web
Enruta las llamadas entrantes dinámicamente usando tu propia lógica de negocio. Hipcall llama a tu servicio web en el momento del timbre y enruta la llamada según tu respuesta JSON.
Llamada Rápida
Activa llamadas salientes de forma programática. Inicia una llamada desde la extensión de un agente a cualquier número a través de una sola solicitud API — ideal para integraciones de clic para llamar.
Gestión Externa
Gestiona tu cuenta de Hipcall desde sistemas externos. Aprovisiona usuarios, actualiza flujos de llamadas y controla la configuración sin iniciar sesión en el panel.
Insight Card
Muestra el contexto del llamante en tiempo real en la pantalla del agente en el momento en que se conecta una llamada. Envía cualquier dato — nombre, empresa, saldo de cuenta — desde tu CRM o ERP a través de la API.