Skip to content

Squads ​

9 endpoints. Every path below is relative to the API base URL and already includes the /api/v1 prefix — see conventions for authentication, pagination, errors and idempotency.

Endpoint
GET/squadsLists the organization's squads with their members and routing table loaded
POST/squadsCreates a draft squad together with its members and routing table in one transaction
GET/squads/{squad}Returns one squad with its members and routing table
PUT/squads/{squad}Updates a squad and, when supplied, replaces its member list and routing table wholesale
DELETE/squads/{squad}Deletes a squad along with its routing table and membership
POST/squads/{squad}/publishValidates the squad's routing graph and freezes it into a new version, returning its id and number
POST/squads/{squad}/resolve-handoffDry-runs the routing table against a hypothetical signal and returns the handoff decision it would make
GET/squads/{squad}/snapshotReturns the routing graph the gateway consumes: squad settings, members and every route in priority order
GET/squads/{squad}/validateRuns the publish-time routing checks without publishing and returns the error list

Endpoints ​

Lists the organization's squads with their members and routing table loaded ​

GET/squads
  • Requires squad.read.
  • Only limit is honoured (default 25, capped at 100); there is no search or status filter.

Query parameters

NameTypeRequiredNotes
limitinteger—default 25
bash
curl -X GET "$CALLAGENT_API_URL/squads?limit=25" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads?limit=25`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads?limit=25');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.get(
    f"{os.environ['CALLAGENT_API_URL']}/squads?limit=25",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
200Paginated set of SquadResource

Errors

StatusWhen it happens
403The key lacks squad.read

Example response, generated from the schema:

json
{
  "data": [
    {
      "id": "01JQ0000000000000000000000",
      "object": "string",
      "name": "Support Line",
      "description": "string",
      "status": "string",
      "is_published": true,
      "version": 1,
      "current_version_id": "01JQ0000000000000000000000",
      "entry_assistant_id": "01JQ0000000000000000000000",
      "handoff_context_mode": "string",
      "handoff_context_size": 1,
      "handoff_extract_variables": {},
      "silent_handoff": true,
      "handoff_message": "string",
      "metadata": {},
      "members": [],
      "routes": [],
      "created_at": "2026-01-01T12:00:00+00:00",
      "updated_at": "2026-01-01T12:00:00+00:00"
    }
  ],
  "links": {
    "first": "string",
    "last": "string",
    "prev": "string",
    "next": "string"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 1,
    "links": [
      {}
    ],
    "path": "string",
    "per_page": 25,
    "to": 1,
    "total": 1
  }
}

Creates a draft squad together with its members and routing table in one transaction ​

POST/squads
  • Requires squad.write.

Request body

FieldTypeRequiredNotes
namestringyesmax 255 chars
descriptionstring | null—max 255 chars
entry_assistant_idstring | null—
handoff_context_modeall_messages · last_n · user_only · user_assistant · summary · none | null—
handoff_context_sizeinteger | null—min 1. max 200
handoff_extract_variablesstring[] | null—
silent_handoffboolean | null—
handoff_messagestring | null—max 2000 chars
metadatastring[] | null—
membersobject[] | null—
routesobject[] | null—
bash
curl -X POST "$CALLAGENT_API_URL/squads" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "name": "Support Line",
       "entry_assistant_id": "01JQ0000000000000000000000",
       "handoff_context_mode": "all_messages",
       "handoff_context_size": 1,
       "silent_handoff": true,
       "members": [
         {
           "assistant_id": "01JQ0000000000000000000000",
           "role": "entry",
           "alias": "string",
           "pin_mode": "latest",
           "assistant_version_id": "01JQ0000000000000000000000",
           "enabled": true
         }
       ],
       "routes": [
         {
           "id": "01JQ0000000000000000000000",
           "name": "Support Line",
           "trigger": "tool",
           "trigger_value": "string",
           "condition": [],
           "destination_type": "assistant",
           "destination_assistant_id": "01JQ0000000000000000000000",
           "destination_squad_id": "01JQ0000000000000000000000",
           "destination_queue_id": "01JQ0000000000000000000000",
           "destination_expression": "string",
           "context_mode": "all_messages",
           "context_size": 1,
           "extract_variables": [],
           "silent": true,
           "message": "string",
           "priority": 1,
           "enabled": true
         }
       ]
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Support Line",
    "entry_assistant_id": "01JQ0000000000000000000000",
    "handoff_context_mode": "all_messages",
    "handoff_context_size": 1,
    "silent_handoff": true,
    "members": [
      {
        "assistant_id": "01JQ0000000000000000000000",
        "role": "entry",
        "alias": "string",
        "pin_mode": "latest",
        "assistant_version_id": "01JQ0000000000000000000000",
        "enabled": true
      }
    ],
    "routes": [
      {
        "id": "01JQ0000000000000000000000",
        "name": "Support Line",
        "trigger": "tool",
        "trigger_value": "string",
        "condition": [],
        "destination_type": "assistant",
        "destination_assistant_id": "01JQ0000000000000000000000",
        "destination_squad_id": "01JQ0000000000000000000000",
        "destination_queue_id": "01JQ0000000000000000000000",
        "destination_expression": "string",
        "context_mode": "all_messages",
        "context_size": 1,
        "extract_variables": [],
        "silent": true,
        "message": "string",
        "priority": 1,
        "enabled": true
      }
    ]
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'name' => 'Support Line',
    'entry_assistant_id' => '01JQ0000000000000000000000',
    'handoff_context_mode' => 'all_messages',
    'handoff_context_size' => 1,
    'silent_handoff' => true,
    'members' => [
        [
            'assistant_id' => '01JQ0000000000000000000000',
            'role' => 'entry',
            'alias' => 'string',
            'pin_mode' => 'latest',
            'assistant_version_id' => '01JQ0000000000000000000000',
            'enabled' => true,
        ],
    ],
    'routes' => [
        [
            'id' => '01JQ0000000000000000000000',
            'name' => 'Support Line',
            'trigger' => 'tool',
            'trigger_value' => 'string',
            'condition' => [],
            'destination_type' => 'assistant',
            'destination_assistant_id' => '01JQ0000000000000000000000',
            'destination_squad_id' => '01JQ0000000000000000000000',
            'destination_queue_id' => '01JQ0000000000000000000000',
            'destination_expression' => 'string',
            'context_mode' => 'all_messages',
            'context_size' => 1,
            'extract_variables' => [],
            'silent' => true,
            'message' => 'string',
            'priority' => 1,
            'enabled' => true,
        ],
    ],
]),
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/squads",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "name": "Support Line",
      "entry_assistant_id": "01JQ0000000000000000000000",
      "handoff_context_mode": "all_messages",
      "handoff_context_size": 1,
      "silent_handoff": True,
      "members": [
        {
          "assistant_id": "01JQ0000000000000000000000",
          "role": "entry",
          "alias": "string",
          "pin_mode": "latest",
          "assistant_version_id": "01JQ0000000000000000000000",
          "enabled": True
        }
      ],
      "routes": [
        {
          "id": "01JQ0000000000000000000000",
          "name": "Support Line",
          "trigger": "tool",
          "trigger_value": "string",
          "condition": [],
          "destination_type": "assistant",
          "destination_assistant_id": "01JQ0000000000000000000000",
          "destination_squad_id": "01JQ0000000000000000000000",
          "destination_queue_id": "01JQ0000000000000000000000",
          "destination_expression": "string",
          "context_mode": "all_messages",
          "context_size": 1,
          "extract_variables": [],
          "silent": True,
          "message": "string",
          "priority": 1,
          "enabled": True
        }
      ]
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
201SquadResource

Errors

StatusWhen it happens
403The key lacks squad.write
422Validation failed, or a referenced assistant/squad is not in this organization

Example response, generated from the schema:

json
{
  "data": {
    "id": "01JQ0000000000000000000000",
    "object": "string",
    "name": "Support Line",
    "description": "string",
    "status": "string",
    "is_published": true,
    "version": 1,
    "current_version_id": "01JQ0000000000000000000000",
    "entry_assistant_id": "01JQ0000000000000000000000",
    "handoff_context_mode": "string",
    "handoff_context_size": 1,
    "handoff_extract_variables": {},
    "silent_handoff": true,
    "handoff_message": "string",
    "metadata": {},
    "members": [
      {}
    ],
    "routes": [
      {}
    ],
    "created_at": "2026-01-01T12:00:00+00:00",
    "updated_at": "2026-01-01T12:00:00+00:00"
  }
}

Returns one squad with its members and routing table ​

GET/squads/{squad}
  • Requires squad.read.

Path parameters

NameTypeRequiredNotes
squadstringyesThe squad ID
bash
curl -X GET "$CALLAGENT_API_URL/squads/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads/01JQ0000000000000000000000`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads/01JQ0000000000000000000000');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.get(
    f"{os.environ['CALLAGENT_API_URL']}/squads/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
200SquadResource

Errors

StatusWhen it happens
403The key lacks squad.read
404No such squad in this organization

Example response, generated from the schema:

json
{
  "data": {
    "id": "01JQ0000000000000000000000",
    "object": "string",
    "name": "Support Line",
    "description": "string",
    "status": "string",
    "is_published": true,
    "version": 1,
    "current_version_id": "01JQ0000000000000000000000",
    "entry_assistant_id": "01JQ0000000000000000000000",
    "handoff_context_mode": "string",
    "handoff_context_size": 1,
    "handoff_extract_variables": {},
    "silent_handoff": true,
    "handoff_message": "string",
    "metadata": {},
    "members": [
      {}
    ],
    "routes": [
      {}
    ],
    "created_at": "2026-01-01T12:00:00+00:00",
    "updated_at": "2026-01-01T12:00:00+00:00"
  }
}

Updates a squad and, when supplied, replaces its member list and routing table wholesale ​

PUT/squads/{squad}
  • Requires squad.write.
  • PATCH is accepted on the same path, with the same body.
  • members and routes are synced only when the key is present, and then they replace the existing set rather than merging.

Path parameters

NameTypeRequiredNotes
squadstringyesThe squad ID

Request body

FieldTypeRequiredNotes
namestring—max 255 chars
descriptionstring | null—max 255 chars
entry_assistant_idstring | null—
handoff_context_modeall_messages · last_n · user_only · user_assistant · summary · none | null—
handoff_context_sizeinteger | null—min 1. max 200
handoff_extract_variablesstring[] | null—
silent_handoffboolean | null—
handoff_messagestring | null—max 2000 chars
metadatastring[] | null—
membersobject[] | null—
routesobject[] | null—
bash
curl -X PUT "$CALLAGENT_API_URL/squads/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "name": "Support Line",
       "entry_assistant_id": "01JQ0000000000000000000000",
       "handoff_context_mode": "all_messages",
       "handoff_context_size": 1,
       "silent_handoff": true,
       "members": [
         {
           "assistant_id": "01JQ0000000000000000000000",
           "role": "entry",
           "alias": "string",
           "pin_mode": "latest",
           "assistant_version_id": "01JQ0000000000000000000000",
           "enabled": true
         }
       ],
       "routes": [
         {
           "id": "01JQ0000000000000000000000",
           "name": "Support Line",
           "trigger": "tool",
           "trigger_value": "string",
           "condition": [],
           "destination_type": "assistant",
           "destination_assistant_id": "01JQ0000000000000000000000",
           "destination_squad_id": "01JQ0000000000000000000000",
           "destination_queue_id": "01JQ0000000000000000000000",
           "destination_expression": "string",
           "context_mode": "all_messages",
           "context_size": 1,
           "extract_variables": [],
           "silent": true,
           "message": "string",
           "priority": 1,
           "enabled": true
         }
       ]
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads/01JQ0000000000000000000000`, {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Support Line",
    "entry_assistant_id": "01JQ0000000000000000000000",
    "handoff_context_mode": "all_messages",
    "handoff_context_size": 1,
    "silent_handoff": true,
    "members": [
      {
        "assistant_id": "01JQ0000000000000000000000",
        "role": "entry",
        "alias": "string",
        "pin_mode": "latest",
        "assistant_version_id": "01JQ0000000000000000000000",
        "enabled": true
      }
    ],
    "routes": [
      {
        "id": "01JQ0000000000000000000000",
        "name": "Support Line",
        "trigger": "tool",
        "trigger_value": "string",
        "condition": [],
        "destination_type": "assistant",
        "destination_assistant_id": "01JQ0000000000000000000000",
        "destination_squad_id": "01JQ0000000000000000000000",
        "destination_queue_id": "01JQ0000000000000000000000",
        "destination_expression": "string",
        "context_mode": "all_messages",
        "context_size": 1,
        "extract_variables": [],
        "silent": true,
        "message": "string",
        "priority": 1,
        "enabled": true
      }
    ]
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads/01JQ0000000000000000000000');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'name' => 'Support Line',
    'entry_assistant_id' => '01JQ0000000000000000000000',
    'handoff_context_mode' => 'all_messages',
    'handoff_context_size' => 1,
    'silent_handoff' => true,
    'members' => [
        [
            'assistant_id' => '01JQ0000000000000000000000',
            'role' => 'entry',
            'alias' => 'string',
            'pin_mode' => 'latest',
            'assistant_version_id' => '01JQ0000000000000000000000',
            'enabled' => true,
        ],
    ],
    'routes' => [
        [
            'id' => '01JQ0000000000000000000000',
            'name' => 'Support Line',
            'trigger' => 'tool',
            'trigger_value' => 'string',
            'condition' => [],
            'destination_type' => 'assistant',
            'destination_assistant_id' => '01JQ0000000000000000000000',
            'destination_squad_id' => '01JQ0000000000000000000000',
            'destination_queue_id' => '01JQ0000000000000000000000',
            'destination_expression' => 'string',
            'context_mode' => 'all_messages',
            'context_size' => 1,
            'extract_variables' => [],
            'silent' => true,
            'message' => 'string',
            'priority' => 1,
            'enabled' => true,
        ],
    ],
]),
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.put(
    f"{os.environ['CALLAGENT_API_URL']}/squads/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "name": "Support Line",
      "entry_assistant_id": "01JQ0000000000000000000000",
      "handoff_context_mode": "all_messages",
      "handoff_context_size": 1,
      "silent_handoff": True,
      "members": [
        {
          "assistant_id": "01JQ0000000000000000000000",
          "role": "entry",
          "alias": "string",
          "pin_mode": "latest",
          "assistant_version_id": "01JQ0000000000000000000000",
          "enabled": True
        }
      ],
      "routes": [
        {
          "id": "01JQ0000000000000000000000",
          "name": "Support Line",
          "trigger": "tool",
          "trigger_value": "string",
          "condition": [],
          "destination_type": "assistant",
          "destination_assistant_id": "01JQ0000000000000000000000",
          "destination_squad_id": "01JQ0000000000000000000000",
          "destination_queue_id": "01JQ0000000000000000000000",
          "destination_expression": "string",
          "context_mode": "all_messages",
          "context_size": 1,
          "extract_variables": [],
          "silent": True,
          "message": "string",
          "priority": 1,
          "enabled": True
        }
      ]
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
200SquadResource

Errors

StatusWhen it happens
403The key lacks squad.write
404No such squad in this organization
422Validation failed, or a referenced assistant/squad is not in this organization

Example response, generated from the schema:

json
{
  "data": {
    "id": "01JQ0000000000000000000000",
    "object": "string",
    "name": "Support Line",
    "description": "string",
    "status": "string",
    "is_published": true,
    "version": 1,
    "current_version_id": "01JQ0000000000000000000000",
    "entry_assistant_id": "01JQ0000000000000000000000",
    "handoff_context_mode": "string",
    "handoff_context_size": 1,
    "handoff_extract_variables": {},
    "silent_handoff": true,
    "handoff_message": "string",
    "metadata": {},
    "members": [
      {}
    ],
    "routes": [
      {}
    ],
    "created_at": "2026-01-01T12:00:00+00:00",
    "updated_at": "2026-01-01T12:00:00+00:00"
  }
}

Deletes a squad along with its routing table and membership ​

DELETE/squads/{squad}
  • Requires squad.write.
  • This response is not data-wrapped.
  • Body is a bare {"deleted": true, "id": "..."}. Deleting a squad needs only squad.write; there is no separate squad.delete permission.

Path parameters

NameTypeRequiredNotes
squadstringyesThe squad ID
bash
curl -X DELETE "$CALLAGENT_API_URL/squads/01JQ0000000000000000000000" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads/01JQ0000000000000000000000`, {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads/01JQ0000000000000000000000');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.delete(
    f"{os.environ['CALLAGENT_API_URL']}/squads/01JQ0000000000000000000000",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
200Bare JSON object, not data-wrapped

Errors

StatusWhen it happens
403The key lacks squad.write
404No such squad in this organization

Example response, generated from the schema:

json
{
  "deleted": true,
  "id": null
}

Validates the squad's routing graph and freezes it into a new version, returning its id and number ​

POST/squads/{squad}/publish
  • Requires squad.write.
  • Returns only {version_id, version}, not a full version resource. Publishing a squad needs only squad.write, unlike assistants which need assistant.publish.

Path parameters

NameTypeRequiredNotes
squadstringyesThe squad ID
bash
curl -X POST "$CALLAGENT_API_URL/squads/01JQ0000000000000000000000/publish" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads/01JQ0000000000000000000000/publish`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads/01JQ0000000000000000000000/publish');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/squads/01JQ0000000000000000000000/publish",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
201data-wrapped object

Errors

StatusWhen it happens
403The key lacks squad.write
404No such squad in this organization
422The squad fails publish-time validation

Example response, generated from the schema:

json
{
  "data": {
    "version_id": null,
    "version": 1
  }
}

Dry-runs the routing table against a hypothetical signal and returns the handoff decision it would make ​

POST/squads/{squad}/resolve-handoff
  • Requires squad.read.
  • Read-only despite being a POST: nothing is persisted. signal is required; messages, variables and from_member_id are optional.

Path parameters

NameTypeRequiredNotes
squadstringyesThe squad ID

Request body

FieldTypeRequiredNotes
signalobjectyes
signal.toolstring | null—
signal.intentstring | null—
variablesstring[] | null—
messagesstring[] | null—
from_member_idstring | null—
bash
curl -X POST "$CALLAGENT_API_URL/squads/01JQ0000000000000000000000/resolve-handoff" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
       "signal": {
         "tool": "string",
         "intent": "string"
       },
       "from_member_id": "01JQ0000000000000000000000"
     }'
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads/01JQ0000000000000000000000/resolve-handoff`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "signal": {
      "tool": "string",
      "intent": "string"
    },
    "from_member_id": "01JQ0000000000000000000000"
  }),
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads/01JQ0000000000000000000000/resolve-handoff');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
    'signal' => [
        'tool' => 'string',
        'intent' => 'string',
    ],
    'from_member_id' => '01JQ0000000000000000000000',
]),
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.post(
    f"{os.environ['CALLAGENT_API_URL']}/squads/01JQ0000000000000000000000/resolve-handoff",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    json={
      "signal": {
        "tool": "string",
        "intent": "string"
      },
      "from_member_id": "01JQ0000000000000000000000"
    },
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
200data-wrapped object

Errors

StatusWhen it happens
403The key lacks squad.read
404No such squad in this organization
422signal is missing or is not an object

Example response, generated from the schema:

json
{
  "data": {
    "matched": true,
    "route_id": null,
    "destination_type": "string",
    "destination": [
      "string"
    ],
    "context_mode": "string",
    "context": [
      "string"
    ],
    "silent": true,
    "message": null,
    "variables": "string",
    "reason": "string"
  }
}

Returns the routing graph the gateway consumes: squad settings, members and every route in priority order ​

GET/squads/{squad}/snapshot
  • Requires squad.read.
  • Built live from the current draft, not from a published version, and carries schema_version for gateway compatibility.

Path parameters

NameTypeRequiredNotes
squadstringyesThe squad ID
bash
curl -X GET "$CALLAGENT_API_URL/squads/01JQ0000000000000000000000/snapshot" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads/01JQ0000000000000000000000/snapshot`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads/01JQ0000000000000000000000/snapshot');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.get(
    f"{os.environ['CALLAGENT_API_URL']}/squads/01JQ0000000000000000000000/snapshot",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
200data-wrapped object

Errors

StatusWhen it happens
403The key lacks squad.read
404No such squad in this organization

Example response, generated from the schema:

json
{
  "data": {
    "schema_version": 1,
    "squad": {
      "id": null,
      "name": "Support Line",
      "entry_assistant_id": "01JQ0000000000000000000000",
      "handoff_context_mode": "string",
      "handoff_context_size": 1,
      "silent_handoff": true,
      "handoff_message": "string",
      "extract_variables": {}
    },
    "members": [
      {}
    ],
    "routes": [
      {}
    ]
  }
}

Runs the publish-time routing checks without publishing and returns the error list ​

GET/squads/{squad}/validate
  • Requires squad.read.
  • A failing squad still answers 200 with valid:false. Catches missing entry assistants, self-handoffs and routes to non-members.

Path parameters

NameTypeRequiredNotes
squadstringyesThe squad ID
bash
curl -X GET "$CALLAGENT_API_URL/squads/01JQ0000000000000000000000/validate" \
  -H "Authorization: Bearer $CALLAGENT_API_KEY" \
  -H "Accept: application/json"
js
const response = await fetch(`${process.env.CALLAGENT_API_URL}/squads/01JQ0000000000000000000000/validate`, {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.type}: ${error.message}`);
}

const { data } = await response.json();
php
<?php

$handle = curl_init(getenv('CALLAGENT_API_URL') . '/squads/01JQ0000000000000000000000/validate');

curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
        'Accept: application/json',
    ],
]);

$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);

if ($status >= 400) {
    throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}

$data = $body['data'];
python
import os, requests

response = requests.get(
    f"{os.environ['CALLAGENT_API_URL']}/squads/01JQ0000000000000000000000/validate",
    headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
data = response.json()["data"]

Responses

StatusBody
200data-wrapped object

Errors

StatusWhen it happens
403The key lacks squad.read
404No such squad in this organization

Example response, generated from the schema:

json
{
  "data": {
    "valid": true,
    "errors": [
      "string"
    ]
  }
}

Documented against the code. Anything not yet implemented is labelled, never described as working.