{"openapi":"3.1.0","info":{"title":"Agent Phone","version":"0.1.0","description":"Sign up or log in to Agent Phone through OAuth. Vapi funds calls within usage limits. Connect the agent to the MCP URL at this service origin plus /mcp; the client handles browser login and credential storage. Never ask the user for bearer tokens, API keys, passwords, or client secrets. Do not use api.vapi.ai or the Vapi SDK for this task. No customer phone-number setup is required."},"servers":[{"url":"https://phone.vapi.ai"}],"security":[{"bearerAuth":[]}],"paths":{"/phone":{"post":{"operationId":"phone","summary":"Queue one goal-driven call","description":"Queued requests include pre-call fraud screening. Call instructions, including context and information, are sent to TypeSafe for fraud screening before dialing. A failed check means no call was placed. A fraud block consumes a call attempt; an unavailable check releases the reservation. Relay the returned message and keep the same request ID/key; never automatically rewrite or resubmit a failed call. If the message says the fraud check could not be completed, ask the user whether to try the identical call again with a new requestKey. Never rewrite instructions to evade a fraud finding. Submitting a request or receiving queued status does not establish that keypad tones were sent. A native send result and remote menu acceptance are separate evidence; never infer either from the input.","parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":8,"maxLength":128},"description":"Reuse this key after a lost response. A different payload with the same key returns 409."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneInput"}}}},"responses":{"200":{"description":"Idempotent replay"},"202":{"description":"Durably queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneResult"}}}},"400":{"description":"Invalid input"},"401":{"description":"Sign in to Agent Phone"},"403":{"description":"User, permission or destination not allowed"},"409":{"description":"Busy or request key conflict"},"429":{"description":"Allowance exhausted"},"503":{"description":"Calling paused or unconfigured"}}}},"/phone/{id}":{"get":{"operationId":"phone_status","summary":"Read an owned call result","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Status and available result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneResult"}}}},"401":{"description":"Sign in to Agent Phone"},"403":{"description":"Permission denied"},"404":{"description":"No owned call found"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"For integration developers: your OAuth client obtains and stores credentials; never ask the user to paste a bearer token or Vapi API key. Prefer connecting the agent to the MCP URL. Alternatively, agents with HTTP and secure credential storage can use device authorization documented at /llms.txt; its opaque credential is accepted by the /phone endpoints, not /mcp. Obtain a Connect access token from https://auth.phone.vapi.ai with audience https://phone.vapi.ai/mcp and the openid grant. Connecting grants both phone tools subject to ownership and call limits. Discover OAuth through https://phone.vapi.ai/.well-known/oauth-protected-resource/mcp."}},"schemas":{"PhoneInput":{"type":"object","additionalProperties":false,"required":["to","goal"],"properties":{"to":{"type":"string","pattern":"^\\+[1-9]\\d{7,14}$"},"goal":{"type":"string","minLength":1,"maxLength":2000,"description":"Describe the user-authorized outcome to obtain. Do not claim transport actions are already completed, such as a key having been pressed or a transfer having succeeded."},"context":{"type":"string","maxLength":4000},"information":{"type":"string","maxLength":4000},"dtmf":{"type":"string","pattern":"^(?:auto|[0-9*#]{1,64})$","description":"Omit or use auto (recommended) to react to announced, task-related keypad options. An exact sequence such as \"1\" constrains the allowed native keypad sequence for the whole call; it does not schedule tones on connection or mean they were already sent. Exact sequences use 1–64 digits, * or #; w/W pauses are unsupported."}}},"PhoneResult":{"type":"object","required":["id","status","transcript","recordingUrl","cost","endedReason","message","pollAfterSeconds","remainingCalls"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"enum":["queued","dispatching","dispatch-uncertain","active","finalizing","ended","failed","deleted"]},"transcript":{"type":["string","null"]},"cost":{"type":["number","null"]},"endedReason":{"type":["string","null"]},"recordingUrl":{"type":["string","null"],"format":"uri","description":"Private Vapi-generated recording link. Signed links expire; read this result again to refresh an expired link. Null until available, when a recording was not produced, and for existing unrecorded calls. Treat this URL as a bearer capability: keep it private and do not publish it."},"message":{"type":["string","null"],"description":"A fixed explanation for pre-call fraud screening failure, a failed connection or clearly repeating phone menu observed in ended call artifacts. Relay it, including when a failed pre-call check has no transcript; a repeating-menu observation does not independently grade the task or prove tone delivery, and a destination not found is not evidence that the service is down. Null when no supported explanation is available. Screening failures are pre-call; other explanations analyze ended call artifacts."},"pollAfterSeconds":{"type":["integer","null"]},"remainingCalls":{"type":"integer","minimum":0,"maximum":10}}}}}}