Update Sub-Account Channels
Set which channels a sub-account can use, and how many of each.
PUT /api/webhooks/agency/:agency_key/sub-accounts/:ref/channels
POST /api/webhooks/agency/:agency_key/sub-accounts/:ref/channelsBoth forms are identical. The POST alias exists for tools that cannot send PUT with a body.
Authentication
Requires a Bearer token with the sub_account.channels scope. See Agency Inbound API.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
ref | string | Sub-account UUID, or ext:<external_ref> |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
channels | object | Yes | The desired final state of every channel |
channels Object
| Field | Type | Description |
|---|---|---|
linkedin | number | LinkedIn accounts allowed (0–100) |
whatsapp | number | WhatsApp numbers allowed (0–100) |
instagram | number | Instagram accounts allowed (0–100) |
email_marketing | number | Email sending domains allowed (0–100) |
The object is declarative
channels is the final state, not a delta. A channel you omit is set to zero and disabled. To raise LinkedIn while keeping WhatsApp, send both.
Non-channel modules — CRM, campaigns, academy — are never touched by this call.
Raising the total number of billable channels charges your agency immediately, pro-rata to the end of the current cycle, on the card on file. If the charge is declined, nothing is applied and the call returns 402 SEAT_CHARGE_FAILED. Lowering the count does not generate a credit.
Response
{
"ok": true,
"event_id": "7c1e9a44-3f7b-4d1b-8f2e-6c5a1b0d9e83",
"data": {
"id": "a1b2c3d4-5678-4e9f-a0b1-c2d3e4f5a6b7",
"channels": {
"linkedin": 3,
"whatsapp": 1,
"instagram": 0,
"email_marketing": 0
},
"delta_channels": 1,
"seat_charge": {
"ok": true,
"paid": true,
"chargedCents": 2450,
"addedChannels": 1
}
}
}delta_channels is the change in billable channels. seat_charge is null when nothing was charged.
Example
cURL
curl --request PUT \
--url "https://api.getraze.co/api/webhooks/agency/AGENCY_KEY/sub-accounts/ext:client-42/channels" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: $(uuidgen)" \
--data '{
"channels": { "linkedin": 3, "whatsapp": 1 }
}'JavaScript
const response = await fetch(
`https://api.getraze.co/api/webhooks/agency/${agencyKey}/sub-accounts/ext:client-42/channels`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID()
},
body: JSON.stringify({
channels: { linkedin: 3, whatsapp: 1 }
})
}
);
const data = await response.json();Python
import requests, uuid
response = requests.put(
f'https://api.getraze.co/api/webhooks/agency/{agency_key}/sub-accounts/ext:client-42/channels',
headers={
'Authorization': f'Bearer {token}',
'Idempotency-Key': str(uuid.uuid4())
},
json={'channels': {'linkedin': 3, 'whatsapp': 1}}
)
data = response.json()Errors
| Status | Code | Description |
|---|---|---|
| 400 | MISSING_FIELDS | channels is absent |
| 400 | INVALID_CHANNELS | Unknown channel, or a value outside 0–100 |
| 401 | UNAUTHORIZED | Missing, unknown or revoked token |
| 402 | SEAT_CHARGE_FAILED | The pro-rata charge was declined; no change was applied |
| 403 | INVALID_SCOPE | Token lacks sub_account.channels |
| 403 | SUB_ACCOUNT_FORBIDDEN | The sub-account belongs to another agency |
| 404 | SUB_ACCOUNT_NOT_FOUND | No live sub-account for that reference |
| 409 | TRIAL_CHANNEL_LOCKED | During the free trial only WhatsApp is available |