List endpoints return results one page at a time. You choose the page with limit and offset. This page covers paging, the few filters that exist and the fixed sort order. Each resource page lists its own filters: finns, deployments, audiences, phone numbers, wallet.
Limit and offset
limit sets the page size. offset sets how many records to skip.
curl "https://api.hirefinn.ai/api/v1/finns?limit=200&offset=0" \
-H "Authorization: Bearer $FINN_API_KEY"
{
"success": true,
"data": [
{ "id": "8f14e45f-ceea-467a-9f6a-1c0e5b2a77d1", "name": "Renewals" },
{ "id": "1c0e5b2a-77d1-4a6e-9b21-8e4c5f7d2a10", "name": "Inbound support" }
],
"limit": 200,
"offset": 0
}
| Field | Type | Description |
|---|---|---|
data | array | The records on this page. |
limit | integer | The page size Finn actually used, after applying the rules below. |
offset | integer | The offset Finn actually used. |
total | integer | Only on GET /audiences/{audience_id}/contacts: the number of contacts in the audience. |
Responses have no cursor, no has_more and, except for contacts, no total. If a page has fewer records than limit, it's the last page.
Page sizes
| Endpoint | Default limit | Maximum limit | Order |
|---|---|---|---|
GET /finns | 50 | 200 | Newest first |
GET /deployments | 50 | 200 | Newest first |
GET /phone_numbers | 50 | 200 | Newest first |
GET /audiences | 50 | 200 | Newest first |
GET /wallet/transactions | 50 | 200 | Newest first |
GET /audiences/{audience_id}/contacts | 100 | 1000 | Order in the contact file |
GET /voices and GET /phone_numbers/available return the whole result in one response and ignore limit and offset. There's no endpoint that lists calls. To read a call, use GET /calls/{call_uuid} with an ID you got from POST /calls or from a webhook.
Finn adjusts out-of-range values instead of rejecting them:
| You send | Finn uses |
|---|---|
limit above the maximum | The maximum |
limit below 1 | 1 |
limit=0, an empty value, or a value that isn't a number | The default |
A negative offset, or one that isn't a number | 0 |
The response always shows the limit and offset Finn actually used. Read them from the response rather than assuming you got what you asked for.
Iterating a full collection
async function listAllFinns(apiKey: string): Promise<unknown[]> {
const results: unknown[] = [];
const limit = 200;
for (let offset = 0; ; offset += limit) {
const url = new URL("https://api.hirefinn.ai/api/v1/finns");
url.searchParams.set("limit", String(limit));
url.searchParams.set("offset", String(offset));
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const page = await res.json();
results.push(...page.data);
if (page.data.length < page.limit) return results;
}
}
import requests
BASE = "https://api.hirefinn.ai/api/v1"
def list_all_finns(api_key):
results, offset, limit = [], 0, 200
while True:
res = requests.get(
f"{BASE}/finns",
headers={"Authorization": f"Bearer {api_key}"},
params={"limit": limit, "offset": offset},
timeout=30,
)
res.raise_for_status()
page = res.json()
results.extend(page["data"])
if len(page["data"]) < page["limit"]:
return results
offset += page["limit"]
Offset paging can go wrong in two ways:
- Records shift while you page. Lists are newest first, so if a record is created while you're paging, every older record moves down one place. You'll see one record twice at a page boundary. Deleting or archiving a record has the opposite effect: you'll skip one. Remove duplicates by
idwhen you combine pages. - Large walks use up your read limit. A
429partway through leaves you with partial results unless you retry. Use the maximumlimit. See rate limits.
Filtering
Filters are query parameters, and only a few endpoints have them:
| Endpoint | Parameter | Values |
|---|---|---|
GET /deployments | status | One lowercase status, for example in_progress. Exact match. |
GET /deployments | call_type | inbound or outbound |
GET /wallet/transactions | types | Up to 20 comma-separated transaction types (letters a to z and _) |
If you send a filter value that doesn't fit the format, you get 400 invalid_request. Finn ignores parameters it doesn't recognize, so check the spelling of filter names. A typo silently returns unfiltered results. There are no date-range filters.
Sorting
Lists are always sorted in the order shown in the Page sizes table. There's no sort parameter, and Finn ignores one if you send it. If you need a different order, fetch the records and sort them yourself.
See API conventions for the request and response rules that apply to every endpoint, and errors for every error code.