Two ways to place a call
Both originate from your number and, in sandbox, are locked to your signup number.
A production key removes that lock.
Read the call log
GET /v1/calls returns your calls newest-first with cursor pagination. Needs the
calls:read scope.
next_cursor back as ?cursor= to page. Destination numbers are masked.
Fetch a recording
GET /v1/calls/{call_id}/recording returns a time-limited download URL (valid
~60 minutes). Needs the recordings:read scope and a production key.
A recording exists only if the call was recorded (via a
<Dial record> or a
background <Record>) and storage is provisioned for
your account. Until then this returns 404 RECORDING_NOT_FOUND or
503 RECORDING_SERVICE_UNAVAILABLE. Sandbox keys get 400 SANDBOX_KEY_NOT_ALLOWED.Control a live call
Change a call while it is live:POST /v1/calls/{call_id}/{action}, where
action is hangup, hold, unhold, mute, unmute, dtmf ({"digits"}),
play ({"url"}, a public https URL), recording/start or recording/stop.
Needs the calls:write scope. A 200 means the voice engine accepted the command.
- Works on calls Wave placed (callbacks and outbound calls) and on inbound
calls to your numbers. Web-calling calls return
409 CALL_NOT_CONTROLLABLE(the SDK controls the browser’s own leg). hangupworks frominitiated; every other action needs anansweredcall.- The optional body field
legpicks the leg:"customer"(default) or"agent", the agent connected now by a<Dial>or a queue. With no connected agent you get409 AGENT_LEG_NOT_CONNECTED. The response tells you the leg.
In-call control is turned on per environment, and the agent leg and the
recording routes each have their own switch. While a switch is off, the
route returns
503 CALL_CONTROL_DISABLED.Transfer a live call
Send the caller somewhere else:POST /v1/calls/{call_id}/transfer with a
target. This is a blind transfer: the caller’s leg goes straight to the
target, with no announcement to the target first. Do not depend on the
current agent leg staying connected after the transfer. Needs the
calls:write scope.
A target that has a bad format or is not your organization’s returns
422 TRANSFER_TARGET_INVALID. The call must be answered, and only one
transfer can be in progress on a call (409 TRANSFER_IN_PROGRESS).
202 at once. When the transfer has a result, Wave sends one
call.transferred webhook with an outcome: answered, no_answer, busy,
failed, cancelled, enqueued (queue target) or expired (the voice engine
did not act on it). If the target does not answer, the call ends. Read a
call’s transfers and their outcomes with GET /v1/calls/{call_id}/transfers
(calls:read scope). On a simulated sandbox call, the transfer completes at
once with outcome answered, and the webhook is marked simulated.
Call transfer has its own switch per environment, and it is not available
in production yet. While it is off, the route returns
503 CALL_CONTROL_DISABLED.Next steps
Web Calling
Place calls from the browser with the SDK.
Webhooks
Get call events pushed to you instead of polling.

