Recipes
Pull today’s calls
Written beside the API’s code, and read from it every hour.
- Ask
GET /v1/callswithsort=day_ascandlimit=500, and raisepageuntil it reachesmeta.total_pages. - Read each call's
journey: one entry per leg, for every menu, group and person. A transcribed leg hassummaryandtranscription. A recorded leg hasrecording_url. recording_urlis an API address. Call it with your key: the answer holds a signedurlthat works for 30 minutes with no key. Download from there.- A call parked and picked up again is recorded in parts. Each leg lists its parts in
recordings, oldest first, each with its ownurl.recording_url,summaryandtranscriptionare the latest part's. To keep every part, fetch each entry ofrecordingsthe same way.
# 1. Today's calls, New York time, 500 a page, oldest first
curl "https://api.vocatech.com/v1/calls?sort=day_asc&limit=500&page=1" \
-H "Authorization: Bearer $VOCATECH_API_KEY"
# 2. A recording: ask for a signed link, then download it with no key (uses jq)
url=$(curl -s https://api.vocatech.com/v1/media/rec_58213407 \
-H "Authorization: Bearer $VOCATECH_API_KEY" | jq -r .url)
curl -o rec_58213407.mp3 "$url"import { writeFile } from 'node:fs/promises';
import { vt } from './vocatech.mjs';
// Today, New York time. Add start_date, end_date and timezone for other days.
for (let page = 1, pages = 1; page <= pages; page++) {
const data = await vt('GET', `/v1/calls?sort=day_asc&limit=500&page=${page}`);
pages = data.meta.total_pages;
for (const call of data.calls) {
for (const leg of call.journey) {
if (leg.summary) console.log(call.call_id, leg.extension_name, leg.summary);
if (leg.recording_url) {
// recording_url is an API address: ask it for a signed download link.
const media = await vt('GET', new URL(leg.recording_url).pathname);
const audio = await fetch(media.url); // no key needed, good for 30 minutes
await writeFile(`${media.id}.${media.format}`, Buffer.from(await audio.arrayBuffer()));
}
}
}
}from urllib.parse import urlparse
import requests
from vocatech import vt
# Today, New York time. Add start_date, end_date and timezone for other days.
page = 1
while True:
data = vt("GET", "/v1/calls", params={"sort": "day_asc", "limit": 500, "page": page})
for call in data["calls"]:
for leg in call["journey"]:
if leg["summary"]:
print(call["call_id"], leg["extension_name"], leg["summary"])
if leg["recording_url"]:
# recording_url is an API address: ask it for a signed download link.
media = vt("GET", urlparse(leg["recording_url"]).path)
audio = requests.get(media["url"], timeout=120) # no key needed
with open(f'{media["id"]}.{media["format"]}', "wb") as f:
f.write(audio.content)
if page >= data["meta"]["total_pages"]:
break
page += 1<?php
require __DIR__ . '/vocatech.php';
// Today, New York time. Add start_date, end_date and timezone for other days.
for ($page = 1, $pages = 1; $page <= $pages; $page++) {
$data = vt('GET', '/v1/calls?' . http_build_query(['sort' => 'day_asc', 'limit' => 500, 'page' => $page]));
$pages = $data['meta']['total_pages'];
foreach ($data['calls'] as $call) {
foreach ($call['journey'] as $leg) {
if ($leg['summary']) {
echo $call['call_id'], ' ', $leg['extension_name'], ': ', $leg['summary'], PHP_EOL;
}
if ($leg['recording_url']) {
// recording_url is an API address: ask it for a signed download link.
$media = vt('GET', parse_url($leg['recording_url'], PHP_URL_PATH));
// The signed link needs no key and works for 30 minutes.
file_put_contents("{$media['id']}.{$media['format']}", file_get_contents($media['url']));
}
}
}
}Transcripts come after the call. They usually land minutes after a call ends and can take longer on a busy day, so a call you pull right away may not have one yet. Pull again later, or subscribe to call.transcription and have it pushed to you.
For another day or range, add start_date, end_date (YYYY-MM-DD) and your timezone. Filters for direction, status, extension and a text search are in the Calls reference.
