message.comDevelopers

Agents Live

Agents are the team members who handle conversations. Every agent has a role (admin, supervisor, agent), a channel scope, and zero or more department memberships. This API covers invite, edit, suspend, and remove.

List agents

GET/api/v1/agentsAuth: Bearer

Cursor-paginated list of agents in the workspace. Optional filters by role, status, and departmentId.

Code samples

cURL
curl 'https://app.message.com/api/v1/agents' \
  -H 'Authorization: Bearer YOUR_WORKSPACE_JWT'
JavaScript
const res = await fetch('https://app.message.com/api/v1/agents', {
  headers: { Authorization: 'Bearer ' + token }
});
const { agents } = await res.json();
Python
import requests
r = requests.get(
    "https://app.message.com/api/v1/agents",
    headers={"Authorization": f"Bearer {token}"},
)
agents = r.json()["agents"]
Ruby
require "net/http"
require "json"
uri = URI("https://app.message.com/api/v1/agents")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  req = Net::HTTP::Get.new(uri)
  req["Authorization"] = "Bearer #{token}"
  http.request(req)
end
agents = JSON.parse(res.body)["agents"]
PHP
<?php
$ctx = stream_context_create([
  "http" => ["method" => "GET", "header" => "Authorization: Bearer $token"]
]);
$agents = json_decode(file_get_contents("https://app.message.com/api/v1/agents", false, $ctx), true)["agents"];

Get one agent

GET/api/v1/agents/:idAuth: Bearer
200 OK
{
  "id": "uuid",
  "version": 5,
  "email": "[email protected]",
  "name": "Alex Lee",
  "role": "agent",
  "channels": ["chat", "ticket"],
  "departments": ["uuid-billing", "uuid-support"],
  "status": "available",
  "avatarUrl": "https://...",
  "suspendedAt": null,
  "createdAt": "2026-01-04T12:00:00Z"
}

Invite an agent

POST/api/v1/agentsAuth: Bearer

Sends an invitation email containing a one-time link the recipient uses to set their password. Pending invites count against the seat cap. Admin-only.

FieldTypeDescription
emailrequiredstringInvitee email. Must be unique across the workspace.
nameoptionalstringDisplay name. Pre-fills the invitee&apos;s profile.
rolerequiredenumOne of admin, supervisor, agent.
channelsoptionalstring[]Subset of chat, ticket, call. Admins implicitly see all channels.
departmentsoptionaluuid[]Initial department memberships.
Body
{
  "email": "[email protected]",
  "name": "Alex Lee",
  "role": "agent",
  "channels": ["chat", "ticket"],
  "departments": ["uuid-billing"]
}

Update an agent

PATCH/api/v1/agents/:idAuth: Bearer

Change role, channels, departments, or display name. Requires expectedVersion. Admins can edit anyone; supervisors can edit only their own department members; agents can edit only themselves (and only name + avatar).

Set status

POST/api/v1/agents/me/statusAuth: Bearer

Sets the calling agent's availability. Drives routing (only available agents receive new assignments) and presence indicators in the inbox.

Body
{ "status": "away" }

Allowed values: available, away, offline.

Suspend / reinstate

POST/api/v1/agents/:id/suspendAuth: Bearer
POST/api/v1/agents/:id/reinstateAuth: Bearer

Suspended agents cannot log in and disappear from routing. Their assigned conversations fall back to their departments. Reinstate is the inverse.

Remove an agent

DELETE/api/v1/agents/:idAuth: Bearer

Permanent removal. The agent record is retained in the audit log; their assigned conversations fall back to the department or workspace queue. Admin-only.

You cannot remove the last admin. The API returns 422 last_admin. Promote someone else first.

Errors

CodeWhen
400 invalid_bodyPayload validation failed.
402 seat_limit_reachedWorkspace is at its seat cap. Upgrade or remove an agent.
403 forbiddenRole does not allow this action (e.g., agent editing another agent).
404 not_foundAgent does not exist in this workspace.
409 conflictEmail already used by another agent in this workspace.
422 last_adminCannot remove or demote the last admin.

Common pitfalls

  • Setting channels for admins. Ignored. Admins always see all channels.
  • Reinstating after a seat change. If your plan dropped below the active agent count, reinstating returns 402 seat_limit_reached. Upgrade first.
  • Looking for a password field. Passwords are set by the invitee via the invite link. There is no admin-set-password endpoint.