Integration Use Case

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.

Webhooks

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

  1. Go to Account > Integrations in your Hipcall dashboard.
  2. Click Create New Integration and choose Webhook.
  3. Configure the webhook:
FieldValue
Target URLhttps://your-server.example.com/webhook/hipcall-cdr
EventsCall Hangup (call_hangup)
MethodPOST

Local development: Use ngrok to expose your local server. Run ngrok http 5007 and 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:

FieldDescription
uuidUnique call identifier — use this to deduplicate
caller_number / callee_numberParties on the call
directioninbound or outbound
call_durationDuration in seconds
record_urlPre-signed URL to the MP3 recording — expires after a short time
hangup_byWho 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

ToolPurpose
WebhooksReceive call_hangup event when a call ends

Next Steps

Ask the Community

Have questions or want to share your integration? Join the discussion.

Tools & APIs

Six ways to extend and integrate Hipcall into your systems.

REST API

Access your Hipcall data programmatically. Manage extensions, initiate calls, retrieve call records, and more via a RESTful HTTP API with OAuth 2.0 and API key authentication.

Webhooks

Receive real-time HTTP notifications for 13+ event types — incoming calls, answered calls, hangups, voicemails, and more. Push call data into any system instantly.

Web Service-Based Smart IVRs

Route incoming calls dynamically using your own business logic. Hipcall calls your web service at ring time and routes the call based on your JSON response.

Quick Call

Trigger outbound calls programmatically. Initiate a call from an agent's extension to any number via a single API request — great for click-to-call integrations.

External Management

Manage your Hipcall account from external systems. Provision users, update call flows, and control settings without logging into the dashboard.

Insight Card

Display real-time caller context on the agent's screen the moment a call connects. Push any data — name, company, account balance — from your CRM or ERP via API.