curl --request POST \
--url https://api.flowiq.live/v1/calls/accept \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"call_id": "wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA",
"sdp": "<string>",
"biz_opaque_callback_data": "<string>"
}
'import requests
url = "https://api.flowiq.live/v1/calls/accept"
payload = {
"call_id": "wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA",
"sdp": "<string>",
"biz_opaque_callback_data": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
call_id: 'wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA',
sdp: '<string>',
biz_opaque_callback_data: '<string>'
})
};
fetch('https://api.flowiq.live/v1/calls/accept', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.flowiq.live/v1/calls/accept",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'call_id' => 'wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA',
'sdp' => '<string>',
'biz_opaque_callback_data' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.flowiq.live/v1/calls/accept"
payload := strings.NewReader("{\n \"call_id\": \"wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA\",\n \"sdp\": \"<string>\",\n \"biz_opaque_callback_data\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.flowiq.live/v1/calls/accept")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"call_id\": \"wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA\",\n \"sdp\": \"<string>\",\n \"biz_opaque_callback_data\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.flowiq.live/v1/calls/accept")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"call_id\": \"wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA\",\n \"sdp\": \"<string>\",\n \"biz_opaque_callback_data\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"organization_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"success": true,
"call_id": "<string>",
"action": "pre_accept"
}{
"error": "Request failed",
"message": "Parameter value is not valid"
}{
"error": "<string>",
"code": "<string>",
"message": "<string>",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"whatsapp_error_code": 123
}{
"error": "Request failed",
"message": "Contact has not granted callback permission"
}{
"error": "<string>",
"code": "<string>",
"message": "<string>",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"whatsapp_error_code": 123
}{
"error": "<string>",
"code": "<string>",
"message": "<string>",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"whatsapp_error_code": 123
}Accept Call
Answer a ringing call. Either send your SDP answer to the offer from the call webhook (the audio then flows between WhatsApp and your media server), or send stream and FlowIQ answers the call itself and streams the audio to your WebSocket (see Media stream). Scope: send.
curl --request POST \
--url https://api.flowiq.live/v1/calls/accept \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"call_id": "wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA",
"sdp": "<string>",
"biz_opaque_callback_data": "<string>"
}
'import requests
url = "https://api.flowiq.live/v1/calls/accept"
payload = {
"call_id": "wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA",
"sdp": "<string>",
"biz_opaque_callback_data": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
call_id: 'wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA',
sdp: '<string>',
biz_opaque_callback_data: '<string>'
})
};
fetch('https://api.flowiq.live/v1/calls/accept', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.flowiq.live/v1/calls/accept",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'call_id' => 'wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA',
'sdp' => '<string>',
'biz_opaque_callback_data' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.flowiq.live/v1/calls/accept"
payload := strings.NewReader("{\n \"call_id\": \"wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA\",\n \"sdp\": \"<string>\",\n \"biz_opaque_callback_data\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.flowiq.live/v1/calls/accept")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"call_id\": \"wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA\",\n \"sdp\": \"<string>\",\n \"biz_opaque_callback_data\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.flowiq.live/v1/calls/accept")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"call_id\": \"wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA\",\n \"sdp\": \"<string>\",\n \"biz_opaque_callback_data\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"organization_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"success": true,
"call_id": "<string>",
"action": "pre_accept"
}{
"error": "Request failed",
"message": "Parameter value is not valid"
}{
"error": "<string>",
"code": "<string>",
"message": "<string>",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"whatsapp_error_code": 123
}{
"error": "Request failed",
"message": "Contact has not granted callback permission"
}{
"error": "<string>",
"code": "<string>",
"message": "<string>",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"whatsapp_error_code": 123
}{
"error": "<string>",
"code": "<string>",
"message": "<string>",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"whatsapp_error_code": 123
}call webhook, after which the audio flows between WhatsApp and your media server, or send stream and FlowIQ answers the call itself and streams the audio to your WebSocket (media stream). If FlowIQ staff have the inbox open, they see the call as answered on another device.
Basic Usage
curl -X POST "https://api.flowiq.live/v1/calls/accept" \
-H "Authorization: Bearer fiq_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"call_id": "wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA", "sdp": "v=0\r\no=- 4611 2 IN IP4 127.0.0.1\r\n…"}'
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
call_id | string | Yes | From the call webhook (call.id) |
sdp | string | One of sdp / stream | Your SDP answer to the offer in call.session.sdp |
stream | object | One of sdp / stream | { url: "wss://…", format?, headers?, custom_parameters? }: FlowIQ answers and streams the audio there. format is pcm16_16k (default), pcm16_8k, pcm16_24k or mulaw_8k |
biz_opaque_callback_data | string | No | With sdp only. Your own reference (max 512 characters); WhatsApp sends it back on later events for this call |
Response
Success (200)
{
"organization_id": "a4234f32-…",
"success": true,
"call_id": "wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA",
"action": "accept"
}
Errors
| Status | When |
|---|---|
400 | call_id, or both sdp and stream, missing (validation_error), or WhatsApp refused the action (whatsapp_rejected; the message says why, e.g. Parameter value is not valid for an unknown or finished call) |
409 | With stream: the call is no longer ringing (call_not_ringing) |
401 | Missing or invalid API key |
403 | The key has no send scope |
stream, a WebSocket endpoint that does not accept the connection within 8 seconds fails the request (validation_error, the message names the reason) and the call keeps ringing.
WhatsApp gives you a limited time to answer before the call rings out; accept as soon as your media server has the answer ready.Authorizations
Your FlowIQ organisation API key (Settings → API Keys), sent as a bearer token. Format: Bearer fiq_YOUR_API_KEY
Body
The call's id from the call webhook
"wacid.HBgLMjc4MjAwMDAwMDAVAgARGBI2RjQ3QkU1RjA5Q0UyMkEzQjQA"
Your SDP answer to the offer in call.session.sdp (leave out when you send stream)
Your own reference; WhatsApp sends it back on later events for this call
512Have FlowIQ answer the call and stream its audio to your WebSocket (media stream), instead of answering with sdp
Show child attributes
Show child attributes

