---
title: "REST API"
description: "CallForMe's REST API at https://callforme.tel/v1: place calls, poll results, answer mid-call questions, share calls, find businesses. curl for every endpoint."
url: https://callforme.tel/docs/rest-api
updated: 2026-09-29
---

# REST API

> The REST API at https://callforme.tel/v1 has the same semantics as the MCP server. POST /calls places a call, GET /calls/:id?wait=30 polls it, POST /calls/:id/answer replies to a mid-call question. Authenticate with Authorization: Bearer cfm_.... The OpenAPI spec is at https://callforme.tel/openapi.json.

## Base URL and auth

```
https://callforme.tel/v1
```

Send your key as a header:

```
Authorization: Bearer cfm_your_key
```

Two ways to get a key:

- **From the first call.** An agent with no key calls `POST /calls`, gets a one-time setup link (below), and the retry returns `account_key` once. Keep it in the `CALLFORME_KEY` env var or your agent's memory.
- **From the account page.** Create one at [callforme.tel/account](https://callforme.tel/account) and give it to your agent.

Agents with a shell can read [https://callforme.tel/skill.md](/docs/skill), which walks through this flow with curl.

OpenAPI: [https://callforme.tel/openapi.json](https://callforme.tel/openapi.json)

## Endpoints

| Method | Path | Same as MCP tool | Key needed |
|---|---|---|---|
| POST | `/calls` | `place_call` | To dial |
| GET | `/calls/:id?wait=30` | `get_call` | Yes |
| POST | `/calls/:id/answer` | `answer_question` | Yes |
| POST | `/calls/:id/hangup` | `hang_up` | Yes |
| POST | `/calls/:id/share` | `share_call` | Yes |
| POST | `/calls/plan` | `plan_call` | No |
| GET | `/businesses?query=&near=` | `find_business` | No |
| GET | `/account` | `account` | Yes |
| GET | `/calls` | `list_calls` | Yes |
| GET | `/pricing` | `pricing` | No |

## Place a call

```bash
curl -X POST https://callforme.tel/v1/calls \
  -H "Authorization: Bearer $CALLFORME_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+19725550100",
    "business_name": "Preston Road Pharmacy",
    "goal": "Find out if they are open on Thanksgiving and until what time.",
    "questions": ["Are you open on Thanksgiving?", "What hours is the pharmacy counter open?"],
    "on_behalf_of": "Sam",
    "callback_number": "+14695550142"
  }'
```

Response:

```json
{ "status": "calling", "call_id": "call_8f2k1" }
```

All `place_call` fields are accepted: `phone`, `goal`, `business_name`, `details`, `questions`, `on_behalf_of`, `callback_number`, `constraints`, `voicemail_message`, `transfer_to`, `language`, `setup_code`, `account_key`. See the [MCP reference](/docs/mcp) for what each does.

### Without a key (first call)

```bash
curl -X POST https://callforme.tel/v1/calls \
  -H "Content-Type: application/json" \
  -d '{"phone": "+19725550100", "goal": "Ask if they are open Thanksgiving."}'
```

HTTP 402:

```json
{
  "status": "needs_setup",
  "setup_url": "https://callforme.tel/go/k7m2q",
  "setup_code": "k7m2q",
  "message_for_user": "To place this call, open https://callforme.tel/go/k7m2q and add $10. Then tell me when you're done."
}
```

Show `message_for_user` to the person. The page shows the exact call; they add $10 (card saved, auto-reload on). After they finish, send the same request with `"setup_code": "k7m2q"`. The call dials and the response includes `account_key` once. Save it and send it as the Bearer header from then on. See [setup links](/docs/setup-links).

### Try the demo line (free)

```bash
curl -X POST https://callforme.tel/v1/calls \
  -H "Content-Type: application/json" \
  -d '{"phone": "+14697707412", "business_name": "Maple Street Pizza", "goal": "Ask how long a large pepperoni takes for pickup."}'
```

Maple Street Pizza is a fictional restaurant. Calls to it need no payment, up to 5 a day.

## Poll a call

```bash
curl "https://callforme.tel/v1/calls/call_8f2k1?wait=30" \
  -H "Authorization: Bearer $CALLFORME_KEY"
```

```json
{
  "status": "ended",
  "transcript": [],
  "pending_question": null,
  "answers": {
    "Are you open on Thanksgiving?": "Yes, 9am to 5pm.",
    "What hours is the pharmacy counter open?": "10am to 2pm."
  },
  "outcome": {
    "success": true,
    "summary": "Open Thanksgiving 9 to 5, pharmacy 10 to 2.",
    "confirmation_number": null,
    "price_quoted": null,
    "appointment_time": null,
    "next_steps": "None."
  },
  "duration_s": 74,
  "cost_usd": 1.00
}
```

`status` is one of `queued`, `ringing`, `in_progress`, `ended`. `wait` can be 0 to 50.

## Answer a mid-call question

When `pending_question` is set:

```bash
curl -X POST https://callforme.tel/v1/calls/call_8f2k1/answer \
  -H "Authorization: Bearer $CALLFORME_KEY" \
  -H "Content-Type: application/json" \
  -d '{"answer": "The date of birth on the prescription is March 3, 1988."}'
```

The assistant waits about 60 seconds for an answer. Reply quickly.

## Hang up

```bash
curl -X POST https://callforme.tel/v1/calls/call_8f2k1/hangup \
  -H "Authorization: Bearer $CALLFORME_KEY"
```

## Share a call

```bash
curl -X POST https://callforme.tel/v1/calls/call_8f2k1/share \
  -H "Authorization: Bearer $CALLFORME_KEY" \
  -H "Content-Type: application/json" \
  -d '{"public": true}'
```

```json
{
  "ok": true,
  "url": "https://callforme.tel/c/r8x2kq",
  "message": "Anyone with this link can read the transcript and result. Phone numbers and emails are hidden."
}
```

Works once the call has ended. The page shows the transcript and result with phone numbers and email addresses hidden. Send `{"public": false}` to take it down.

## Plan a call (no key)

```bash
curl -X POST https://callforme.tel/v1/calls/plan \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+19725550100",
    "goal": "Book a full groom for a 60 lb goldendoodle next Saturday.",
    "details": "Owner name Sam."
  }'
```

Returns the opening line, a checklist, likely questions the business will ask that you haven't covered, whether the business is open now, and a cost estimate.

## Find a business (no key)

```bash
curl "https://callforme.tel/v1/businesses?query=dog%20groomer&near=Plano%2C%20TX"
```

Returns name, phone, address, open now, hours today and rating for each match.

## Account

```bash
curl https://callforme.tel/v1/account \
  -H "Authorization: Bearer $CALLFORME_KEY"
```

Returns your balance, whether auto-reload is on, and a top-up link.

## List calls

```bash
curl https://callforme.tel/v1/calls \
  -H "Authorization: Bearer $CALLFORME_KEY"
```

## Pricing (no key)

```bash
curl https://callforme.tel/v1/pricing
```

## A full script

```bash
#!/usr/bin/env bash
set -euo pipefail
KEY="$CALLFORME_KEY"
ID=$(curl -s -X POST https://callforme.tel/v1/calls \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"phone":"+19725550100","goal":"Ask if order 4411 is ready for pickup.","on_behalf_of":"Sam"}' \
  | jq -r .call_id)

while true; do
  R=$(curl -s "https://callforme.tel/v1/calls/$ID?wait=30" -H "Authorization: Bearer $KEY")
  S=$(echo "$R" | jq -r .status)
  [ "$S" = "ended" ] && { echo "$R" | jq .outcome; break; }
done
```

For automation tools, see [n8n, Zapier and Make](/agents/automations).

## FAQ

### Are the field names the same as the MCP tools?

Yes. The POST /calls body uses the same fields as place_call, and the responses match get_call.

### Which endpoints work without a key?

POST /calls/plan, GET /businesses and GET /pricing. POST /calls to the demo line is free. Any other POST /calls without a key returns needs_setup with a one-time setup link, and the retry returns your key.

### How does long polling work?

Add ?wait=30 to GET /calls/:id. The request returns when the status changes, a question comes in, or the wait runs out. Up to 50 seconds.

### Can I use this from n8n, Zapier or Make?

Yes. Any HTTP step can call it. See the automations page for examples.
