Foyer API pages

Foyer API · Recipe

Search everything a caller said

Find the call where someone mentioned "the roof", a policy number, or a name, across everything callers said to Foyer and to you.

You need: a key with calls:read and transcripts:read (any plan). With calls:read alone, search covers names, numbers and summaries only.

Search for words

GET /v1/search?q=… matches the whole phrase, ignoring case, in the caller's name, caller ID name, company, number and Foyer's summary. With transcripts:read it also looks in voicemail text, the screening conversation and the recorded call's transcript, and each hit has a short excerpt around the match and matched_in, the places it matched.

curl
curl "https://api.hifoyer.com/v1/search?q=roof" \
  -H "Authorization: Bearer $FOYER_API_KEY"

Calls are stored encrypted, so one search request examines up to 400 calls, newest first. If next_cursor is not null, there is older history: pass it back as cursor to keep going. search.reached_oldest_call is true when nothing older is left.

Python: search all of your history
import os
import time

import requests

API = "https://api.hifoyer.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['FOYER_API_KEY']}"}


def search(q, **filters):
    cursor = None
    while True:
        params = {"q": q, "limit": 50, **filters, **({"cursor": cursor} if cursor else {})}
        resp = requests.get(f"{API}/search", headers=HEADERS, params=params, timeout=30)
        if resp.status_code == 429:
            time.sleep(int(resp.headers.get("Retry-After", "5")))
            continue
        resp.raise_for_status()
        page = resp.json()
        yield from page["data"]
        cursor = page["next_cursor"]
        if not cursor:
            return


for hit in search("roof"):
    call = hit["call"]
    who = call["caller"]["name"] or call["caller"]["number"] or "Unknown caller"
    print(call["started_at"][:10], who, "|", ", ".join(hit["matched_in"]), "|", hit["excerpt"] or call["summary"])

Search counts against its own limit of 20 a minute. Narrow a long search with since, until or outcome.

Everything one caller said

List one caller's calls with GET /v1/calls?caller=… (the full number), then read each in full:

Python: one caller's words, oldest first
number = "+16175550142"
calls = requests.get(f"{API}/calls", headers=HEADERS, params={"caller": number, "limit": 100}, timeout=30)
calls.raise_for_status()
for item in reversed(calls.json()["data"]):
    detail = requests.get(f"{API}/calls/{item['id']}", headers=HEADERS, timeout=30)
    detail.raise_for_status()
    call = detail.json()["data"]
    print(f"\n{call['started_at']}: {call['outcome_label']}")
    for turn in call.get("screening_conversation", []):
        print(f"  {turn['speaker']}: {turn['text']}")
    if call["voicemail"].get("transcript"):
        print(f"  voicemail: {call['voicemail']['transcript']}")
    for turn in (call.get("connected_call") or {}).get("transcript", []):
        print(f"  {turn['speaker']}: {turn['text']}")

In the screening conversation, speaker is caller or foyer. In a recorded call it is caller or you.

Ask an assistant instead

With Foyer connected to Claude or ChatGPT, ask: "Find the call where someone talked about the roof, and tell me what they said." See Connect Claude or ChatGPT.