{"openapi":"3.1.0","info":{"title":"call4me API","version":"1.3.0","description":"Phone calls an AI agent places for its user: call a business, follow the call to its outcome, answer the caller's questions mid-call, and patch the user in. Also the prepaid balance, the caller profile, scheduled calls, the account's phone numbers and call recordings. The same operations as the MCP server at /mcp. Calls are billed per minute from pickup (phone menus and conversation; hold time at half price) from the prepaid balance; unanswered calls are free. Refusals name MCP tools (call4me_place_call is POST /api/calls, call4me_save_profile is PATCH /api/profile).","x-guidance":"With a wallet and no account: POST /api/x402/calls with the call (to, business, goal, category, details, on_behalf_of, max_minutes) and pay the 402 in USDC on Base. A refusal (422 \"Not calling yet\") lists what to ask the user and takes no payment. The paid response returns the call id and an api_key; follow the call with GET /api/calls/{call_id}?wait_seconds=30 and Authorization: Bearer <api_key> until finished, answering open questions with POST /api/calls/{call_id}/answer. With an account: the bearer routes below, and GET /api to buy credits in USDC.","contact":{"name":"call4me","email":"me@call4.me","url":"https://call4.me"}},"servers":[{"url":"https://call4.me"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A call4me API key or OAuth access token for the site or MCP resource."}}},"paths":{"/api":{"get":{"operationId":"buyCredits","description":"Buy call credits in USDC on Base over x402 for the account named by the bearer token. Without a payment: 402 with the price of `amount` dollars of credits.","security":[{"bearerAuth":[]}],"parameters":[{"name":"amount","in":"query","required":false,"description":"dollars of credits, 10 to 500 (default 10)","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"number","minimum":10,"maximum":500}}],"x-payment-info":{"price":{"mode":"dynamic","currency":"USD","min":"10.00","max":"500.00"},"protocols":[{"x402":{}}]},"responses":{"200":{"description":"Credited","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"credited":{"type":"string"},"credited_cents":{"type":"number"},"balance":{"type":"string"},"balance_cents":{"type":"number"},"transaction":{"type":"string"},"payer":{"type":"string"}},"required":["credited","credited_cents","balance","balance_cents","transaction","payer"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"402":{"description":"Payment required: the x402 v2 requirements, also in the PAYMENT-REQUIRED header","content":{"application/json":{"schema":{"type":"object","properties":{"x402Version":{"type":"integer"},"accepts":{"type":"array","items":{"type":"object"}}},"required":["x402Version","accepts"]}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/x402/calls":{"post":{"operationId":"placePaidCall","description":"Place a call paid in USDC on Base over x402, with no call4me account: the payment is max_minutes (default 10, up to 60) at the destination's per-minute price, and the paying wallet becomes a call4me account. The call is checked before payment settles: 422 \"Not calling yet\" lists what to ask the user and takes nothing. Returns the call and the account's api_key; follow it with GET /api/calls/{call_id}. Minutes the call does not use stay as credits on that account.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"to":{"type":"string","minLength":3,"maxLength":40,"description":"the number to call, e.g. \"+14155550123\", \"(415) 555-0123\", or abroad with its country code, e.g. \"+31 20 123 4567\""},"business":{"type":"string","minLength":1,"maxLength":120,"description":"who you are calling, as a person would say it: \"Nopa\", \"Dr. Chen's office\", \"Toyota of Berkeley service\""},"goal":{"type":"string","minLength":5,"maxLength":1500,"description":"what the call should achieve, in plain words: \"Book a table for 4 tomorrow (Sat Oct 3) around 7pm under Khami.\""},"category":{"type":"string","enum":["medical","dental","restaurant","veterinary","auto_service","auto_sales","home_service","personal_care","internet_new_service","internet_existing_account","flight_change","general"],"description":"the kind of call; decides what must be known first (see call4me_get_requirements)"},"details":{"description":"answers to the category's fields by key, e.g. {\"reason\":\"annual physical\",\"patient_status\":\"existing\",\"availability\":\"weekday mornings next week\"}. Profile fields (name, DOB, phone, insurance...) are filled from the saved profile only when the call is for the profile's owner; for anyone else (on_behalf_of is another name) pass all of their details here, since the owner's are never used.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":1000}},"on_behalf_of":{"description":"who the call is for, as the caller should say it (default: the profile's full_name). The caller calls FOR this person; it never claims to be them.","type":"string","minLength":1,"maxLength":80},"facts":{"description":"anything else the caller may share beyond the category's fields, one per line","type":"string","maxLength":3000},"flexibility":{"description":"what the caller may accept without asking: \"any time 6:30-8pm\", \"a different day this week is fine\", \"up to $300\". Anything outside this becomes a question to you.","type":"string","maxLength":1500},"timezone":{"description":"IANA time zone of the business, e.g. \"America/Los_Angeles\", so \"tomorrow\" is unambiguous","type":"string","maxLength":60},"connect_when":{"description":"when to ring the user and patch them into the call without being asked, e.g. \"as soon as a person picks up\" (skip the hold) or \"if they need to speak to me\". Rings their own phone: details.phone when given, else the one in their profile; a call with neither is refused. They hand the call back to the caller by pressing * or hanging up.","type":"string","maxLength":300},"listen_in":{"description":"ring the user as soon as the business answers so they can listen in: nobody on the call hears them and the caller keeps working. They press 1 anytime to take over, or hang up to stop listening. Rings their own phone: details.phone when given, else the one in their profile; a call with neither is refused.","type":"boolean"},"max_minutes":{"description":"the most minutes the answered call may run, including phone menus (default 10); the payment is this many minutes at the destination's per-minute price. Minutes the call does not use stay as credits on the paying wallet's call4me account","type":"integer","minimum":1,"maximum":60},"voice":{"description":"caller voice (default marin); hear each at https://call4.me/voices","type":"string","enum":["marin","cedar","gleam","meridian","vesper","willow"]},"caller_name":{"description":"a first name the caller introduces itself with, e.g. \"Jordan\", for this call only (default: the profile's assistant_name, else none: just \"<user>'s assistant\"). Put the caller's name and company here, never in the goal: the caller's identity comes only from these fields.","type":"string","maxLength":30},"calling_as":{"description":"a company the caller calls from, e.g. \"Acme\": it introduces itself as \"Jordan from Acme\" (or \"calling from Acme\" without caller_name) instead of \"<user>'s assistant\", and callbacks to the number it called from answer as that company. Calling for several companies: pass the company on every call and give each one its own number (from), so callbacks reach the right identity.","type":"string","minLength":1,"maxLength":80},"callback_number":{"description":"the number the caller gives for call-backs and on voicemail, when the user wants callbacks to ring a phone of theirs (e.g. \"(415) 555-0123\"). Default: the number the call comes from, so a call4me number answers the callback and finishes the task. A callback to callback_number goes straight to that phone instead, and call4me never hears it. Phone numbers in details or facts are only for finding or verifying an account, never given as the callback.","type":"string","maxLength":40},"from":{"description":"which of the account's numbers to call from (default: a call4me number in the callee's country). May be one of the user's own verified numbers (call4me_verify_number), for businesses in its country: they see it and call back the user directly","type":"string","maxLength":40}},"required":["to","business","goal","category"],"additionalProperties":false}}}},"x-payment-info":{"price":{"mode":"dynamic","currency":"USD","min":"0.25","max":"39.00"},"protocols":[{"x402":{}}]},"responses":{"201":{"description":"Paid and dialing","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"call":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","dialing","in_progress","completed","no_answer","busy","failed","canceled"]},"finished":{"type":"boolean","description":"true once the call ended and its recap is written; poll until then"},"direction":{"type":"string","enum":["outbound","inbound"]},"business":{"type":"string"},"number":{"type":"string"},"calling_number":{"description":"the call4me number that rings the user when they join","type":["string","null"]},"goal":{"type":["string","null"]},"outcome":{"anyOf":[{"type":"object","properties":{"result":{"type":"string"},"summary":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["result","summary"],"additionalProperties":{}},{"type":"null"}]},"open_questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"}},"required":["id","question"],"additionalProperties":{}},"description":"the business is waiting on the line: answer right away"},"answered_questions":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}},"required":["question","answer"],"additionalProperties":{}}},"talk_minutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"cost":{"type":"string"},"cost_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"billed so far, in US cents; final once finished"},"ended":{"description":"who ended the call and why","type":["string","null"]},"error":{"type":["string","null"]},"created_at":{"type":"string"},"transcript":{"type":"array","items":{"type":"string"}}},"required":["id","status","finished","direction","business","number","calling_number","goal","outcome","open_questions","answered_questions","talk_minutes","cost","cost_cents","ended","error","created_at"],"additionalProperties":{}},"api_key":{"type":"string"},"follow":{"type":"string"},"credited":{"type":"string"},"credited_cents":{"type":"number"},"balance":{"type":"string"},"balance_cents":{"type":"number"},"transaction":{"type":"string"},"payer":{"type":"string"}},"required":["call","api_key","follow","credited","credited_cents","balance","balance_cents","transaction","payer"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"402":{"description":"Payment required: the x402 v2 requirements, also in the PAYMENT-REQUIRED header","content":{"application/json":{"schema":{"type":"object","properties":{"x402Version":{"type":"integer"},"accepts":{"type":"array","items":{"type":"object"}}},"required":["x402Version","accepts"]}}}},"403":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"422":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/balance":{"get":{"operationId":"getBalance","description":"The prepaid balance, the per-minute price (and the destinations priced differently), and the account's call4me numbers. Free.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The balance and numbers","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"balance":{"type":"string"},"balance_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"price_per_minute":{"type":"string"},"price_per_minute_by_country":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"minutes_left":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"phone_number":{"type":["string","null"]},"numbers":{"type":"array","items":{"type":"object","properties":{"number":{"type":"string"},"e164":{"type":"string"}},"required":["number","e164"],"additionalProperties":{}}}},"required":["balance","balance_cents","price_per_minute","price_per_minute_by_country","minutes_left","phone_number","numbers"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/requirements":{"get":{"operationId":"listCallCategories","description":"The kinds of call (category slugs) call4me places. Each decides what must be known before dialing. Free.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The categories","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"categories":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"examples":{"type":"string"}},"required":["slug","name","examples"],"additionalProperties":{}}}},"required":["categories"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/requirements/{category}":{"get":{"operationId":"getCallRequirements","description":"The information a kind of call needs before dialing, and which of it the saved profile already has. Ask the user for every required field not known, in one message, then pass the answers in details when placing the call. Free.","security":[{"bearerAuth":[]}],"parameters":[{"name":"category","in":"path","required":true,"description":"a category slug from /api/requirements, e.g. \"restaurant\"","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string"}}],"responses":{"200":{"description":"What the call needs","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"category":{"type":"string"},"name":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"required":{"type":"boolean"},"ask":{"type":"string"},"from_profile":{"type":["string","null"]},"known":{"type":"boolean"}},"required":["key","label","required","ask","from_profile","known"],"additionalProperties":{}}}},"required":["category","name","fields"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/profile":{"get":{"operationId":"getProfile","description":"Saved details reused on relevant calls (name, DOB, phone, address, insurance, car). An incomplete profile is fine. Free.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The saved profile","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"profile":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"missing":{"type":"array","items":{"type":"string"}}},"required":["profile"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"patch":{"operationId":"saveProfile","description":"Save facts that are the same on every call. Merges into what is saved; an empty string removes a field. Save only what the user agreed to keep.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"full_name":{"description":"full name","type":"string","maxLength":500},"name_pronunciation":{"description":"name pronunciation","type":"string","maxLength":500},"assistant_name":{"description":"assistant name","type":"string","maxLength":500},"answering_instructions":{"description":"answering instructions","type":"string","maxLength":500},"date_of_birth":{"description":"date of birth","type":"string","maxLength":500},"phone":{"description":"phone number","type":"string","maxLength":500},"email":{"description":"email","type":"string","maxLength":500},"address":{"description":"home address","type":"string","maxLength":500},"insurance_carrier":{"description":"health insurance carrier","type":"string","maxLength":500},"insurance_member_id":{"description":"health insurance member ID","type":"string","maxLength":500},"insurance_group_number":{"description":"health insurance group number","type":"string","maxLength":500},"dental_insurance_carrier":{"description":"dental insurance carrier","type":"string","maxLength":500},"dental_insurance_member_id":{"description":"dental insurance member ID","type":"string","maxLength":500},"vehicle":{"description":"vehicle (year, make, model, mileage)","type":"string","maxLength":500},"vin":{"description":"VIN","type":"string","maxLength":500},"frequent_flyer_numbers":{"description":"frequent flyer numbers","type":"string","maxLength":500},"known_traveler_number":{"description":"Known Traveler Number (TSA PreCheck / Global Entry)","type":"string","maxLength":500},"redress_number":{"description":"TSA Redress number","type":"string","maxLength":500}},"additionalProperties":false}}}},"responses":{"200":{"description":"The profile now saved","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"profile":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"missing":{"type":"array","items":{"type":"string"}}},"required":["profile"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/calls":{"get":{"operationId":"listCalls","description":"Recent calls, newest first (without transcripts), and scheduled calls that have not dialed yet. Free.","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"1 to 50, default 10","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"The calls","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"calls":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","dialing","in_progress","completed","no_answer","busy","failed","canceled"]},"finished":{"type":"boolean","description":"true once the call ended and its recap is written; poll until then"},"direction":{"type":"string","enum":["outbound","inbound"]},"business":{"type":"string"},"number":{"type":"string"},"calling_number":{"description":"the call4me number that rings the user when they join","type":["string","null"]},"goal":{"type":["string","null"]},"outcome":{"anyOf":[{"type":"object","properties":{"result":{"type":"string"},"summary":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["result","summary"],"additionalProperties":{}},{"type":"null"}]},"open_questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"}},"required":["id","question"],"additionalProperties":{}},"description":"the business is waiting on the line: answer right away"},"answered_questions":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}},"required":["question","answer"],"additionalProperties":{}}},"talk_minutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"cost":{"type":"string"},"cost_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"billed so far, in US cents; final once finished"},"ended":{"description":"who ended the call and why","type":["string","null"]},"error":{"type":["string","null"]},"created_at":{"type":"string"},"transcript":{"type":"array","items":{"type":"string"}}},"required":["id","status","finished","direction","business","number","calling_number","goal","outcome","open_questions","answered_questions","talk_minutes","cost","cost_cents","ended","error","created_at"],"additionalProperties":{}}},"scheduled":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","dialing","placed","failed","canceled"]},"business":{"type":"string"},"number":{"type":"string"},"call_at":{"type":"string"},"call_id":{"description":"the call it became, once dialed","type":["string","null"]}},"required":["id","status","business","number","call_at","call_id"],"additionalProperties":{}}}},"required":["calls","scheduled"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"operationId":"placeCall","description":"Call a business for the user and have a natural conversation to get something done (book, reschedule, cancel, ask). Refuses with 422 \"Not calling yet\" until the category's required information is known, listing exactly what to ask the user. Returns at once with the call; follow it with GET /api/calls/{call_id}?wait_seconds=30 until finished, answering any open question right away. Credits for the maximum length are held up front; billed per minute from pickup (phone menus and conversation; hold time at half price), rounded up; unanswered calls are free.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique value per request (a UUID), kept on retries of it. A retry with the same key and body returns the call the first request made (200, with Idempotent-Replayed: true) instead of placing another; the same key with a different body is refused (422). Keys belong to the account and never expire. A request refused before anything was placed (422 \"Not calling yet\", 402) does not use up its key.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"to":{"type":"string","minLength":3,"maxLength":40,"description":"the number to call, e.g. \"+14155550123\", \"(415) 555-0123\", or abroad with its country code, e.g. \"+31 20 123 4567\""},"business":{"type":"string","minLength":1,"maxLength":120,"description":"who you are calling, as a person would say it: \"Nopa\", \"Dr. Chen's office\", \"Toyota of Berkeley service\""},"goal":{"type":"string","minLength":5,"maxLength":1500,"description":"what the call should achieve, in plain words: \"Book a table for 4 tomorrow (Sat Oct 3) around 7pm under Khami.\""},"category":{"type":"string","enum":["medical","dental","restaurant","veterinary","auto_service","auto_sales","home_service","personal_care","internet_new_service","internet_existing_account","flight_change","general"],"description":"the kind of call; decides what must be known first (see call4me_get_requirements)"},"details":{"description":"answers to the category's fields by key, e.g. {\"reason\":\"annual physical\",\"patient_status\":\"existing\",\"availability\":\"weekday mornings next week\"}. Profile fields (name, DOB, phone, insurance...) are filled from the saved profile only when the call is for the profile's owner; for anyone else (on_behalf_of is another name) pass all of their details here, since the owner's are never used.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":1000}},"on_behalf_of":{"description":"who the call is for, as the caller should say it (default: the profile's full_name). The caller calls FOR this person; it never claims to be them.","type":"string","minLength":1,"maxLength":80},"facts":{"description":"anything else the caller may share beyond the category's fields, one per line","type":"string","maxLength":3000},"flexibility":{"description":"what the caller may accept without asking: \"any time 6:30-8pm\", \"a different day this week is fine\", \"up to $300\". Anything outside this becomes a question to you.","type":"string","maxLength":1500},"timezone":{"description":"IANA time zone of the business, e.g. \"America/Los_Angeles\", so \"tomorrow\" is unambiguous","type":"string","maxLength":60},"connect_when":{"description":"when to ring the user and patch them into the call without being asked, e.g. \"as soon as a person picks up\" (skip the hold) or \"if they need to speak to me\". Rings their own phone: details.phone when given, else the one in their profile; a call with neither is refused. They hand the call back to the caller by pressing * or hanging up.","type":"string","maxLength":300},"listen_in":{"description":"ring the user as soon as the business answers so they can listen in: nobody on the call hears them and the caller keeps working. They press 1 anytime to take over, or hang up to stop listening. Rings their own phone: details.phone when given, else the one in their profile; a call with neither is refused.","type":"boolean"},"max_minutes":{"description":"optional cap on the answered call, including phone menus. Defaults to 30 minutes, or less if the available balance cannot cover it. Only credits for that cap are held. A call still on hold when it reaches the cap keeps waiting: call4me holds 15 more minutes of credits at a time while the balance covers them, up to 4 hours. One still mid-conversation at the cap gets 2 more minutes at a time to finish instead of hanging up. Set a shorter cap to leave more credits free for other calls","type":"integer","minimum":1,"maximum":240},"voice":{"description":"caller voice (default marin); hear each at https://call4.me/voices","type":"string","enum":["marin","cedar","gleam","meridian","vesper","willow"]},"caller_name":{"description":"a first name the caller introduces itself with, e.g. \"Jordan\", for this call only (default: the profile's assistant_name, else none: just \"<user>'s assistant\"). Put the caller's name and company here, never in the goal: the caller's identity comes only from these fields.","type":"string","maxLength":30},"calling_as":{"description":"a company the caller calls from, e.g. \"Acme\": it introduces itself as \"Jordan from Acme\" (or \"calling from Acme\" without caller_name) instead of \"<user>'s assistant\", and callbacks to the number it called from answer as that company. Calling for several companies: pass the company on every call and give each one its own number (from), so callbacks reach the right identity.","type":"string","minLength":1,"maxLength":80},"callback_number":{"description":"the number the caller gives for call-backs and on voicemail, when the user wants callbacks to ring a phone of theirs (e.g. \"(415) 555-0123\"). Default: the number the call comes from, so a call4me number answers the callback and finishes the task. A callback to callback_number goes straight to that phone instead, and call4me never hears it. Phone numbers in details or facts are only for finding or verifying an account, never given as the callback.","type":"string","maxLength":40},"from":{"description":"which of the account's numbers to call from (default: a call4me number in the callee's country). May be one of the user's own verified numbers (call4me_verify_number), for businesses in its country: they see it and call back the user directly","type":"string","maxLength":40}},"required":["to","business","goal","category"],"additionalProperties":false}}}},"responses":{"200":{"description":"A retry under the same Idempotency-Key: the call the first request placed","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","dialing","in_progress","completed","no_answer","busy","failed","canceled"]},"finished":{"type":"boolean","description":"true once the call ended and its recap is written; poll until then"},"direction":{"type":"string","enum":["outbound","inbound"]},"business":{"type":"string"},"number":{"type":"string"},"calling_number":{"description":"the call4me number that rings the user when they join","type":["string","null"]},"goal":{"type":["string","null"]},"outcome":{"anyOf":[{"type":"object","properties":{"result":{"type":"string"},"summary":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["result","summary"],"additionalProperties":{}},{"type":"null"}]},"open_questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"}},"required":["id","question"],"additionalProperties":{}},"description":"the business is waiting on the line: answer right away"},"answered_questions":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}},"required":["question","answer"],"additionalProperties":{}}},"talk_minutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"cost":{"type":"string"},"cost_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"billed so far, in US cents; final once finished"},"ended":{"description":"who ended the call and why","type":["string","null"]},"error":{"type":["string","null"]},"created_at":{"type":"string"},"transcript":{"type":"array","items":{"type":"string"}}},"required":["id","status","finished","direction","business","number","calling_number","goal","outcome","open_questions","answered_questions","talk_minutes","cost","cost_cents","ended","error","created_at"],"additionalProperties":{}}}}},"201":{"description":"The call, dialing","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","dialing","in_progress","completed","no_answer","busy","failed","canceled"]},"finished":{"type":"boolean","description":"true once the call ended and its recap is written; poll until then"},"direction":{"type":"string","enum":["outbound","inbound"]},"business":{"type":"string"},"number":{"type":"string"},"calling_number":{"description":"the call4me number that rings the user when they join","type":["string","null"]},"goal":{"type":["string","null"]},"outcome":{"anyOf":[{"type":"object","properties":{"result":{"type":"string"},"summary":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["result","summary"],"additionalProperties":{}},{"type":"null"}]},"open_questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"}},"required":["id","question"],"additionalProperties":{}},"description":"the business is waiting on the line: answer right away"},"answered_questions":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}},"required":["question","answer"],"additionalProperties":{}}},"talk_minutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"cost":{"type":"string"},"cost_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"billed so far, in US cents; final once finished"},"ended":{"description":"who ended the call and why","type":["string","null"]},"error":{"type":["string","null"]},"created_at":{"type":"string"},"transcript":{"type":"array","items":{"type":"string"}}},"required":["id","status","finished","direction","business","number","calling_number","goal","outcome","open_questions","answered_questions","talk_minutes","cost","cost_cents","ended","error","created_at"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"402":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"422":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/calls/{call_id}":{"get":{"operationId":"getCall","description":"Status, open questions, live transcript and, once finished, the outcome and cost of a call. With wait_seconds it waits for something to change (a new question, the call finishing) before answering. Takes a scheduled id (sched_...) too. Free.","security":[{"bearerAuth":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"description":"a call id (\"call_...\") or a scheduled id (\"sched_...\")","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string"}},{"name":"wait_seconds","in":"query","required":false,"description":"0 to 50, default 0","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"integer","minimum":0,"maximum":50}}],"responses":{"200":{"description":"The call (with scheduled when it came from a schedule), or a schedule not dialed yet","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","dialing","in_progress","completed","no_answer","busy","failed","canceled"]},"finished":{"type":"boolean","description":"true once the call ended and its recap is written; poll until then"},"direction":{"type":"string","enum":["outbound","inbound"]},"business":{"type":"string"},"number":{"type":"string"},"calling_number":{"description":"the call4me number that rings the user when they join","type":["string","null"]},"goal":{"type":["string","null"]},"outcome":{"anyOf":[{"type":"object","properties":{"result":{"type":"string"},"summary":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["result","summary"],"additionalProperties":{}},{"type":"null"}]},"open_questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"}},"required":["id","question"],"additionalProperties":{}},"description":"the business is waiting on the line: answer right away"},"answered_questions":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}},"required":["question","answer"],"additionalProperties":{}}},"talk_minutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"cost":{"type":"string"},"cost_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"billed so far, in US cents; final once finished"},"ended":{"description":"who ended the call and why","type":["string","null"]},"error":{"type":["string","null"]},"created_at":{"type":"string"},"transcript":{"type":"array","items":{"type":"string"}}},"required":["id","status","finished","direction","business","number","calling_number","goal","outcome","open_questions","answered_questions","talk_minutes","cost","cost_cents","ended","error","created_at"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/calls/{call_id}/answer":{"post":{"operationId":"answerQuestion","description":"Answer a question the caller asked mid-call (open_questions). The caller relays it on the line within a second or two. Answer in a few plain words.","security":[{"bearerAuth":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"description":"the call id from placing or listing calls (\"call_...\")","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"question_id":{"type":"string","minLength":1,"maxLength":40},"answer":{"type":"string","minLength":1,"maxLength":1000,"description":"e.g. \"Yes, 8:15 works.\" or \"The reservation is under Khami.\""}},"required":["question_id","answer"],"additionalProperties":false}}}},"responses":{"200":{"description":"Sent to the caller","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"},"answer":{"type":"string"}},"required":["id","question","answer"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/calls/{call_id}/connect":{"post":{"operationId":"connectUser","description":"Ring the user now and patch them into a live call. They join by pressing 1; the caller goes quiet and takes back over when they press * or hang up. Mode \"listen\" lets them listen in without being heard. Tell the user before calling this.","security":[{"bearerAuth":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"description":"the call id from placing or listing calls (\"call_...\")","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"phone":{"description":"a different number to ring, e.g. \"(415) 555-0123\"","type":"string","maxLength":40},"mode":{"default":"join","description":"\"join\" (default): they take the call over by pressing 1. \"listen\": they listen in while the caller keeps working, and can press 1 anytime to take over","type":"string","enum":["join","listen"]}},"required":["mode"],"additionalProperties":false}}}},"responses":{"200":{"description":"Ringing the user","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"call_id":{"type":"string"},"message":{"type":"string"}},"required":["call_id","message"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/calls/{call_id}/hang-up":{"post":{"operationId":"hangUp","description":"End a call in progress now. Talk time so far is billed as usual.","security":[{"bearerAuth":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"description":"the call id from placing or listing calls (\"call_...\")","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string"}}],"responses":{"200":{"description":"Hanging up","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"call_id":{"type":"string"},"message":{"type":"string"}},"required":["call_id","message"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/scheduled-calls":{"post":{"operationId":"scheduleCall","description":"Place a call later (the business is closed, or the user wants it at a set time). Takes everything POST /api/calls takes, plus call_at, and checks it now. Nobody may be following the call when it runs, so give every fact and all the flexibility it needs up front. Credits are held when it dials.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique value per request (a UUID), kept on retries of it. A retry with the same key and body returns the scheduled call the first request made (200, with Idempotent-Replayed: true) instead of placing another; the same key with a different body is refused (422). Keys belong to the account and never expire. A request refused before anything was placed (422 \"Not calling yet\", 402) does not use up its key.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"to":{"type":"string","minLength":3,"maxLength":40,"description":"the number to call, e.g. \"+14155550123\", \"(415) 555-0123\", or abroad with its country code, e.g. \"+31 20 123 4567\""},"business":{"type":"string","minLength":1,"maxLength":120,"description":"who you are calling, as a person would say it: \"Nopa\", \"Dr. Chen's office\", \"Toyota of Berkeley service\""},"goal":{"type":"string","minLength":5,"maxLength":1500,"description":"what the call should achieve, in plain words: \"Book a table for 4 tomorrow (Sat Oct 3) around 7pm under Khami.\""},"category":{"type":"string","enum":["medical","dental","restaurant","veterinary","auto_service","auto_sales","home_service","personal_care","internet_new_service","internet_existing_account","flight_change","general"],"description":"the kind of call; decides what must be known first (see call4me_get_requirements)"},"details":{"description":"answers to the category's fields by key, e.g. {\"reason\":\"annual physical\",\"patient_status\":\"existing\",\"availability\":\"weekday mornings next week\"}. Profile fields (name, DOB, phone, insurance...) are filled from the saved profile only when the call is for the profile's owner; for anyone else (on_behalf_of is another name) pass all of their details here, since the owner's are never used.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":1000}},"on_behalf_of":{"description":"who the call is for, as the caller should say it (default: the profile's full_name). The caller calls FOR this person; it never claims to be them.","type":"string","minLength":1,"maxLength":80},"facts":{"description":"anything else the caller may share beyond the category's fields, one per line","type":"string","maxLength":3000},"flexibility":{"description":"what the caller may accept without asking: \"any time 6:30-8pm\", \"a different day this week is fine\", \"up to $300\". Anything outside this becomes a question to you.","type":"string","maxLength":1500},"timezone":{"description":"IANA time zone of the business, e.g. \"America/Los_Angeles\", so \"tomorrow\" is unambiguous","type":"string","maxLength":60},"connect_when":{"description":"when to ring the user and patch them into the call without being asked, e.g. \"as soon as a person picks up\" (skip the hold) or \"if they need to speak to me\". Rings their own phone: details.phone when given, else the one in their profile; a call with neither is refused. They hand the call back to the caller by pressing * or hanging up.","type":"string","maxLength":300},"listen_in":{"description":"ring the user as soon as the business answers so they can listen in: nobody on the call hears them and the caller keeps working. They press 1 anytime to take over, or hang up to stop listening. Rings their own phone: details.phone when given, else the one in their profile; a call with neither is refused.","type":"boolean"},"max_minutes":{"description":"optional cap on the answered call, including phone menus. Defaults to 30 minutes, or less if the available balance cannot cover it. Only credits for that cap are held. A call still on hold when it reaches the cap keeps waiting: call4me holds 15 more minutes of credits at a time while the balance covers them, up to 4 hours. One still mid-conversation at the cap gets 2 more minutes at a time to finish instead of hanging up. Set a shorter cap to leave more credits free for other calls","type":"integer","minimum":1,"maximum":240},"voice":{"description":"caller voice (default marin); hear each at https://call4.me/voices","type":"string","enum":["marin","cedar","gleam","meridian","vesper","willow"]},"caller_name":{"description":"a first name the caller introduces itself with, e.g. \"Jordan\", for this call only (default: the profile's assistant_name, else none: just \"<user>'s assistant\"). Put the caller's name and company here, never in the goal: the caller's identity comes only from these fields.","type":"string","maxLength":30},"calling_as":{"description":"a company the caller calls from, e.g. \"Acme\": it introduces itself as \"Jordan from Acme\" (or \"calling from Acme\" without caller_name) instead of \"<user>'s assistant\", and callbacks to the number it called from answer as that company. Calling for several companies: pass the company on every call and give each one its own number (from), so callbacks reach the right identity.","type":"string","minLength":1,"maxLength":80},"callback_number":{"description":"the number the caller gives for call-backs and on voicemail, when the user wants callbacks to ring a phone of theirs (e.g. \"(415) 555-0123\"). Default: the number the call comes from, so a call4me number answers the callback and finishes the task. A callback to callback_number goes straight to that phone instead, and call4me never hears it. Phone numbers in details or facts are only for finding or verifying an account, never given as the callback.","type":"string","maxLength":40},"from":{"description":"which of the account's numbers to call from (default: a call4me number in the callee's country). May be one of the user's own verified numbers (call4me_verify_number), for businesses in its country: they see it and call back the user directly","type":"string","maxLength":40},"call_at":{"type":"string","minLength":10,"maxLength":40,"description":"when to dial: the business's local time like \"2026-10-05T09:15\" together with timezone, or an ISO time with its offset like \"2026-10-05T09:15:00-07:00\". Pick a time the business is open and answering (a little after opening beats right at it). Up to 60 days ahead; dials within a minute of it."}},"required":["to","business","goal","category","call_at"],"additionalProperties":false}}}},"responses":{"200":{"description":"A retry under the same Idempotency-Key: the call the first request scheduled","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","dialing","placed","failed","canceled"]},"business":{"type":"string"},"number":{"type":"string"},"call_at":{"type":"string"},"call_id":{"description":"the call it became, once dialed","type":["string","null"]}},"required":["id","status","business","number","call_at","call_id"],"additionalProperties":{}}}}},"201":{"description":"The scheduled call","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","dialing","placed","failed","canceled"]},"business":{"type":"string"},"number":{"type":"string"},"call_at":{"type":"string"},"call_id":{"description":"the call it became, once dialed","type":["string","null"]}},"required":["id","status","business","number","call_at","call_id"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"422":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/scheduled-calls/{scheduled_id}":{"delete":{"operationId":"cancelScheduledCall","description":"Cancel a scheduled call before it dials.","security":[{"bearerAuth":[]}],"parameters":[{"name":"scheduled_id","in":"path","required":true,"description":"the id from POST /api/scheduled-calls (\"sched_...\")","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string"}}],"responses":{"200":{"description":"The canceled schedule","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","dialing","placed","failed","canceled"]},"business":{"type":"string"},"number":{"type":"string"},"call_at":{"type":"string"},"call_id":{"description":"the call it became, once dialed","type":["string","null"]}},"required":["id","status","business","number","call_at","call_id"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/numbers":{"get":{"operationId":"listNumbers","description":"The account's phone numbers, and the countries more can be bought in with today's prices. Calls go out from a number in the callee's country when the account holds one. US, Canadian and European businesses can always be called (Europe from a European number if the account has one, else from its US number), and UAE and Japanese businesses too, from the account's US number (the business sees a US caller ID); elsewhere, a number in the country is what lets the account call there. Numbers cost exactly what the carrier charges: the upfront cost plus the first month when bought, then the monthly cost every 30 days, taken from the balance. own_numbers are the user's own phone numbers verified with call4me_verify_number: free, and used only when call4me_place_call names one in from.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The account's numbers and the countries more can be bought in","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"numbers":{"type":"array","items":{"type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"type":{"type":"string","description":"local, mobile, national or toll_free"},"included":{"type":"boolean","description":"the free number that came with the account"},"monthly":{"type":"string"},"monthly_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"renews":{"description":"date the next monthly charge is due; null for the free number","type":["string","null"]},"overdue":{"type":"boolean","description":"the last renewal failed for lack of credits"},"release_after":{"description":"when an overdue number is released unless credits are added","type":["string","null"]}},"required":["number","e164","country","country_name","type","included","monthly","monthly_cents","renews","overdue","release_after"],"additionalProperties":{}}},"pending_numbers":{"description":"numbers paid for and waiting on the carrier's approval (numbers abroad are reviewed first, minutes to a few days). They activate by themselves and cannot place calls until they move to numbers. Omitted when there are none","type":"array","items":{"type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"type":{"type":"string","description":"local, mobile, national or toll_free"},"monthly":{"type":"string"},"monthly_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"ordered":{"type":"string","description":"date it was bought; it activates once the carrier approves it, and its first month starts then"}},"required":["number","e164","country","country_name","type","monthly","monthly_cents","ordered"],"additionalProperties":{}}},"own_numbers":{"description":"the user's own phone numbers, verified to call from: calls go out from one only when place_call names it in from. Omitted when the account has none","type":"array","items":{"type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"status":{"type":"string","enum":["pending","verified"],"description":"pending: the code was sent and has not come back yet"},"method":{"type":"string","enum":["sms","call"],"description":"how the code was sent"},"verified_at":{"type":["string","null"]}},"required":["number","e164","country","country_name","status","method","verified_at"],"additionalProperties":{}}},"countries":{"type":"array","items":{"type":"object","properties":{"country":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"available":{"type":"boolean"},"reason":{"description":"why a number cannot be bought there right now","type":["string","null"]},"upfront_cents":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"monthly_cents":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"price":{"description":"taken from the balance when buying: upfront cost plus the first month","type":["string","null"]},"monthly":{"type":["string","null"]}},"required":["country","name","type","available","reason","upfront_cents","monthly_cents","price","monthly"],"additionalProperties":{}}}},"required":["numbers","countries"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"operationId":"buyNumber","description":"Buy another phone number, in the US or abroad, paid from the balance at the carrier's own price (see call4me_list_numbers for prices). It renews from the balance every 30 days; if the balance can't cover a renewal the number is released after 7 days. Only buy when the user asks for a number or needs one to call a country. A number abroad is reviewed by the carrier after it's paid for, from minutes to a few days: it comes back pending, activates by itself, and can't place calls until then.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"country":{"type":"string","pattern":"^[A-Za-z]{2}$","description":"ISO country code from the countries list, e.g. \"NL\", \"GB\", \"CA\", \"US\""},"area_code":{"description":"preferred area code (national destination code), e.g. \"415\" or \"20\"; the nearest available is used otherwise","type":"string","pattern":"^\\d{2,5}$"}},"required":["country"],"additionalProperties":false}}}},"responses":{"201":{"description":"The number bought, ready to call from","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"type":{"type":"string","description":"local, mobile, national or toll_free"},"included":{"type":"boolean","description":"the free number that came with the account"},"monthly":{"type":"string"},"monthly_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"renews":{"description":"date the next monthly charge is due; null for the free number","type":["string","null"]},"overdue":{"type":"boolean","description":"the last renewal failed for lack of credits"},"release_after":{"description":"when an overdue number is released unless credits are added","type":["string","null"]}},"required":["number","e164","country","country_name","type","included","monthly","monthly_cents","renews","overdue","release_after"],"additionalProperties":{}}}}},"202":{"description":"The number bought and waiting on the carrier's approval; it activates by itself","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"pending":{"type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"type":{"type":"string","description":"local, mobile, national or toll_free"},"monthly":{"type":"string"},"monthly_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"ordered":{"type":"string","description":"date it was bought; it activates once the carrier approves it, and its first month starts then"}},"required":["number","e164","country","country_name","type","monthly","monthly_cents","ordered"],"additionalProperties":{}}},"required":["pending"],"additionalProperties":false}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"402":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"503":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/numbers/{number}":{"delete":{"operationId":"releaseNumber","description":"Give up one of the account's bought numbers. Its monthly charge stops; what was already paid is not refunded, and the number cannot be gotten back. The free number that came with the account cannot be released. Only do this when the user asks.","security":[{"bearerAuth":[]}],"parameters":[{"name":"number","in":"path","required":true,"description":"E.164, URL-encoded (+ as %2B)","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":3,"maxLength":40,"description":"one of the account's numbers, e.g. \"+31612345678\""}}],"responses":{"200":{"description":"The number released","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"type":{"type":"string","description":"local, mobile, national or toll_free"},"included":{"type":"boolean","description":"the free number that came with the account"},"monthly":{"type":"string"},"monthly_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"renews":{"description":"date the next monthly charge is due; null for the free number","type":["string","null"]},"overdue":{"type":"boolean","description":"the last renewal failed for lack of credits"},"release_after":{"description":"when an overdue number is released unless credits are added","type":["string","null"]}},"required":["number","e164","country","country_name","type","included","monthly","monthly_cents","renews","overdue","release_after"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/numbers/own":{"post":{"operationId":"sendNumberVerification","description":"Send a verification code to the user's own phone number: a text, or a call that reads the code out. Submit the code with POST /api/numbers/own/{number}/verify. At most 5 codes a day.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"number":{"type":"string","minLength":3,"maxLength":40,"description":"the user's own phone number, e.g. \"+14155550123\" or \"(415) 555-0123\""},"method":{"default":"sms","description":"how to send the code: a text, or a call that reads it out (for landlines)","type":"string","enum":["sms","call"]},"extension":{"description":"keys the verification call dials once answered, to get past a phone menu to an extension; w waits half a second, W one second. method \"call\" only","type":"string","pattern":"^[0-9A-D*#wW]{1,50}$"}},"required":["number","method"],"additionalProperties":false}}}},"responses":{"202":{"description":"The code was sent; the number waits on it","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"status":{"type":"string","enum":["pending","verified"],"description":"pending: the code was sent and has not come back yet"},"method":{"type":"string","enum":["sms","call"],"description":"how the code was sent"},"verified_at":{"type":["string","null"]}},"required":["number","e164","country","country_name","status","method","verified_at"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/numbers/own/{number}/verify":{"post":{"operationId":"confirmNumberVerification","description":"Submit the code the user's own number received. Once accepted, calls can go out from it (from in call4me_place_call), to businesses in its own country.","security":[{"bearerAuth":[]}],"parameters":[{"name":"number","in":"path","required":true,"description":"E.164, URL-encoded (+ as %2B)","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":3,"maxLength":40,"description":"one of the user's own numbers on the account, e.g. \"+14155550123\""}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","pattern":"^[0-9A-Za-z]{3,12}$","description":"the code the user received"}},"required":["code"],"additionalProperties":false}}}},"responses":{"200":{"description":"The number, verified","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"status":{"type":"string","enum":["pending","verified"],"description":"pending: the code was sent and has not come back yet"},"method":{"type":"string","enum":["sms","call"],"description":"how the code was sent"},"verified_at":{"type":["string","null"]}},"required":["number","e164","country","country_name","status","method","verified_at"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/numbers/own/{number}":{"delete":{"operationId":"removeOwnNumber","description":"Stop calling from one of the user's own numbers, or drop one still waiting on its code. Verifying it again needs a new code. Only do this when the user asks.","security":[{"bearerAuth":[]}],"parameters":[{"name":"number","in":"path","required":true,"description":"E.164, URL-encoded (+ as %2B)","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":3,"maxLength":40,"description":"one of the user's own numbers on the account, e.g. \"+14155550123\""}}],"responses":{"200":{"description":"The number removed","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"number":{"type":"string","description":"formatted for people"},"e164":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"country_name":{"type":"string"},"status":{"type":"string","enum":["pending","verified"],"description":"pending: the code was sent and has not come back yet"},"method":{"type":"string","enum":["sms","call"],"description":"how the code was sent"},"verified_at":{"type":["string","null"]}},"required":["number","e164","country","country_name","status","method","verified_at"],"additionalProperties":{}}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/calls/{call_id}/recordings":{"get":{"operationId":"getCallRecordings","description":"Get existing recordings of a finished call owned by the signed in account. Returns fresh download links when available. An empty list means no recording is available yet. Links may expire; request this again for fresh links. Only share the links with the user.","security":[{"bearerAuth":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":1,"maxLength":40,"description":"The call id returned when placing or listing calls."}}],"responses":{"200":{"description":"Available recordings and fresh download links","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"call_id":{"type":"string"},"recordings":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"download_urls":{"type":"object","properties":{"mp3":{"type":"string","format":"uri"},"wav":{"type":"string","format":"uri"}},"additionalProperties":{}},"duration_millis":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"started_at":{"type":["string","null"]},"ended_at":{"type":["string","null"]}},"required":["id","download_urls","duration_millis","started_at","ended_at"],"additionalProperties":{}}},"message":{"type":"string"}},"required":["call_id","recordings","message"],"additionalProperties":{}}}}},"400":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"Request failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}}}}