Go from a developer credential to a single call record, using curl, in about five minutes.
curl.jq (optional, for pulling values out of JSON responses).All examples use the base URL https://portal.unidenvoice.com/api/v1. Set your credential in shell variables first so the commands below can be pasted as-is:
API_USER="your-credential-username"
API_PASS="your-30-character-password"
Or use read -s API_PASS so the password isn't saved to your shell history.
POST /authentication with form fields username and password.
curl -s -X POST https://portal.unidenvoice.com/api/v1/authentication \
-d "username=$API_USER" \
-d "password=$API_PASS"
Response:
{"success":true,"token":"eyJ0eXAiOiJK...","expire_at":"2026-09-24 14:53:29"}
Capture the token in one step:
TOKEN=$(curl -s -X POST https://portal.unidenvoice.com/api/v1/authentication \
-d "username=$API_USER" -d "password=$API_PASS" | jq -r .token)
Send it on every other request as a header: Authorization: Bearer $TOKEN.
| Behaviour | Detail |
|---|---|
| Token lifetime | 60 minutes from issue (expire_at). |
| Re-authenticating before expiry | Returns the same token, not a new one. |
| Wrong credentials | HTTP 400 {"success":false,"message":"Login credentials are invalid."} |
GET /calls/outbound or GET /calls/inbound. Results are newest first.
curl -s -H "Authorization: Bearer $TOKEN" \
"https://portal.unidenvoice.com/api/v1/calls/inbound?dateFrom=2026-09-01"
| Parameter | What it does |
|---|---|
dateFrom, dateTo |
Date range, e.g. 2026-09-01 or 2026-09-01 00:00:00. Australia/Sydney time. Defaults to the current calendar month. |
perPage |
Records per page. Default 10, maximum 50. |
page |
Page number. |
type |
Inbound only: inbound or inbound-1300. |
Response:
{
"status": 201,
"message": "Ok",
"data": {
"data": [
{
"id": "968a1c90-b7a1-467c-8a71-bc4ef1368585",
"id_legacy": 218885742,
"date": "2026-09-22 17:52:57",
"destination_number": "61485978024",
"extension": null,
"callerid": "61370688761",
"billed_seconds": 6,
"total_time_seconds": 7,
"call_cost": null,
"asterisk_unique_ID": "syd-voice-01.vocphone.com-1790063577.5702619",
"audio_id": "",
"download_url": ""
}
],
"total": 1,
"total_pages": 1
}
}
The list endpoints report "status": 201 on success. That's expected.
Note the id of the call you want. total and total_pages tell you how much more there is to page through. For pulling large date ranges and building statistics, see Generating call statistics with the V1 Calls API.
GET /calls/get/{id}. Accepts either the UUID id or the numeric id_legacy.
CALL_ID="968a1c90-b7a1-467c-8a71-bc4ef1368585"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://portal.unidenvoice.com/api/v1/calls/get/$CALL_ID"
Response:
{
"status": 200,
"message": "Ok",
"data": {
"id": "968a1c90-b7a1-467c-8a71-bc4ef1368585",
"id_legacy": 218885742,
"date": "2026-09-22 17:52:57",
"direction": "inbound",
"extension": null,
"destination_number": "61485978024",
"destination_geo_tag": "",
"callerid": "61370688761",
"callerid_name": null,
"billed_seconds": 6,
"call_cost": "0.0000000",
"call_summary": "No summary available",
"has_transcription": true,
"download_url": "https://portal.vocphone.com/api/v1/calls/968a1c90-b7a1-467c-8a71-bc4ef1368585/download?type=recording",
"transcript_url": "https://portal.vocphone.com/api/v1/calls/968a1c90-b7a1-467c-8a71-bc4ef1368585/download?type=transcript"
}
}
| Field | Meaning |
|---|---|
id |
Call UUID. Use this for downloads. |
id_legacy |
Numeric call id. |
date |
Call start time, Australia/Sydney. |
direction |
inbound or outbound. |
extension |
Extension on the call, or null if none. Use the value from this endpoint. |
destination_number |
Number dialled. |
destination_geo_tag |
Destination class, e.g. National. |
callerid |
Caller's number. |
callerid_name |
Caller's name, if presented. |
billed_seconds |
Answered talk time. 0 means the call was not answered. |
call_cost |
Call cost in AUD, as a decimal string. |
call_summary |
AI summary, if the call was transcribed. |
has_transcription |
Whether a transcript exists. |
download_url |
Recording download link (see step 4). |
transcript_url |
Transcript download link (see step 4). |
The download links may use the portal.vocphone.com host. Both hosts accept the same token.
GET /calls/{id}/download?type=recording returns WAV audio (audio/x-wav). ?type=transcript returns plain text.
curl -s -H "Authorization: Bearer $TOKEN" -o call.wav \
"https://portal.unidenvoice.com/api/v1/calls/$CALL_ID/download?type=recording"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://portal.unidenvoice.com/api/v1/calls/$CALL_ID/download?type=transcript"
Downloads need the UUID
id, notid_legacy. A recording only exists if call recording was on for that call, and calls whoseidisnull(older records) cannot be downloaded via the API.
Token problems come back as HTTP 200 with a status message in the body, not as a 401. Check the response body, not just the HTTP code.
| Response | Cause / fix |
|---|---|
{"status":"Token is expired."} |
Tokens last 60 minutes. Repeat step 1. |
{"status":"Token is invalid."} |
Check the value in the Authorization header. |
{"status":"The token could not be parsed from the request"} |
The Authorization: Bearer header is missing. |
HTTP 400 Login credentials are invalid. |
Wrong username or password. Copy the password again from Account → Developer Options (eye or copy icon). You can show it at any time. |
HTTP 403 Per page count should not exceed 50 |
Lower perPage to 50 or less. |
HTTP 404 Call not found. on download |
You passed id_legacy. Use the UUID id. |