OpenPhn docs

OpenAI Agents

Give an OpenAI Agent a phone tool via the OpenPhn API.

Like with the Claude Agent SDK, there's no OpenAI-specific OpenPhn SDK. Wire it in as a function-calling tool over REST.

from openai import OpenAI
import os, uuid, requests

client = OpenAI()

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "openphn_make_call",
            "description": "Place a phone call via OpenPhn. Returns call_id.",
            "parameters": {
                "type": "object",
                "required": ["to", "objective", "outcome_schema", "consent_type"],
                "properties": {
                    "to":             {"type": "string"},
                    "objective":      {"type": "string"},
                    "outcome_schema": {"type": "object"},
                    "consent_type":   {
                        "type": "string",
                        "enum": [
                            "prior_express",
                            "existing_business_relationship",
                            "emergency",
                        ],
                    },
                },
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "openphn_get_call",
            "description": "Fetch an OpenPhn call's current state and outcome.",
            "parameters": {
                "type": "object",
                "required": ["call_id"],
                "properties": {"call_id": {"type": "string"}},
            },
        },
    },
]

BASE = "https://api.openphn.com"
HEADERS = {"Authorization": f"Bearer {os.environ['OPENPHN_KEY']}"}


def handle_openphn(name: str, args: dict) -> dict:
    if name == "openphn_make_call":
        r = requests.post(
            f"{BASE}/v1/calls",
            headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
            json=args,
            timeout=10,
        )
        return r.json()
    if name == "openphn_get_call":
        r = requests.get(f"{BASE}/v1/calls/{args['call_id']}", headers=HEADERS, timeout=10)
        return r.json()
    raise ValueError(f"unknown tool: {name}")

Polling vs webhooks

OpenAI Agents can't receive webhook POSTs. Two patterns work:

  1. Poll in-loop — the agent calls openphn_get_call every N seconds until status == "completed". Fine for one-off calls under a minute.
  2. Queue and return — the agent fires make_call and ends its turn. A separate worker consumes OpenPhn's webhook (signed; see Webhooks) and writes the outcome back to your conversation store. The next agent turn finds the outcome and continues.

For batch / high-volume workloads, pattern 2 scales; pattern 1 keeps agent latency budget under control for single calls.

Same rule as with Claude Agents — consent_type should be passed in by your orchestration layer, not inferred by the model. See Consent & opt-in.

On this page