# Pull today’s calls

1. Ask `GET /v1/calls` with `sort=day_asc` and `limit=500`, and raise `page` until it reaches `meta.total_pages`.
2. Read each call's `journey`: one entry per leg, for every menu, group and person. A transcribed leg has `summary` and `transcription`. A recorded leg has `recording_url`.
3. `recording_url` is an API address. Call it with your key: the answer holds a signed `url` that works for 30 minutes with no key. Download from there.
4. A call parked and picked up again is recorded in parts. Each leg lists its parts in `recordings`, oldest first, each with its own `url`. `recording_url`, `summary` and `transcription` are the latest part's. To keep every part, fetch each entry of `recordings` the same way.

**curl**

```bash
# 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"
```

**Node**

```javascript
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()));
      }
    }
  }
}
```

**Python**

```python
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**

```php
<?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](https://vocatech.com/developers/guide/calls).
