A dedicated Partner Portal route, not part of the /bizai/** catch-all. The Postman
collection's /bizai/thread_control is only a sub-path the catch-all would forward; use this one.
Partner Portal forwards the body unchanged to WASS, which fills phone_number_id from the app and
calls Meta POST /{phone_number_id}/thread_control. Passing control changes who answers a live
conversation. release hands it back and, per Meta, emits no handover webhook.
Meta errors on this route are Graph-style ((#100) ..., code 2494191 when take is not permitted),
not the {title, detail} envelope used on /bizai/**.
Rate limit: 500 requests per 60 seconds per app, separate from /bizai/**. Only application/json
is accepted (415 otherwise).
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
Request parameters
| Parameter | Type | Required | In | Description |
|---|---|---|---|---|
Authorization | string | Yes | Header | Partner app token, sent raw. Bearer <token> is also accepted. |
Content-Type | string | Yes | Header | application/json |
appId | string (uuid) | Yes | Path | Partner Portal app id. Stands in for Meta's entity_id. |
messaging_product | string | Yes | Body | Always whatsapp. |
to | string | Yes | Body | Consumer phone number. |
action | string | Yes | Body | One of: pass, release, take. |
metadata | string | No | Body | Optional context passed to the new owner. Max 2000 chars. |
control_pass | object | No | Body | Only valid with action = pass. |
control_pass.target_role | string | Yes | Body | The Business Agent reference accepts only ai_agent. One of: ai_agent. |
Example request
curl --location --request POST 'https://partner.gupshup.io/partner/app/<appId>/thread/control' \
--header 'Authorization: <PARTNER_APP_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"messaging_product": "whatsapp",
"action": "pass",
"to": "+919999999999",
"metadata": "optional context string",
"control_pass": {
"target_role": "ai_agent"
}
}'Response parameters — 200
200| Parameter | Type | Description |
|---|---|---|
messaging_product | string | Always whatsapp. |
success | boolean | true when the request succeeded. |
Example response — 200 OK
200 OK{
"messaging_product": "whatsapp"
}Error responses
400 Bad Request — The app is not live. No trailing full stop on this route.
{
"message": "App is not live",
"status": "error"
}401 Unauthorized — Authorization is missing or invalid, belongs to another app, or appId is unknown or not a UUID.
{
"status": "error",
"message": "Unauthorised access to the resource. Please review request parameters and headers and retry"
}405 Method Not Allowed — Any method other than POST.
{
"status": "error",
"message": "Request method 'GET' is not supported"
}415 Unsupported Media Type — Body is not application/json.
{
"status": "error",
"message": "Content-Type 'text/plain' is not supported"
}429 Too Many Requests — More than 500 requests in 60 seconds for this app. Body shape as observed on /bizai/**.
{
"status": "error",
"message": "Too Many Requests"
} 429Per-app rate limit exceeded. Retry after the 60-second window.
