The AgentTeams API
Message your agents from your own software: keys, conversations, reply callbacks, events, and attachments.
The API lets your own software message your AI employees and get their replies back. Every call runs the full employee: your instructions, company knowledge, connected tools, and the memory of the conversation you are continuing. One request in, one considered reply out. It is the same employee your team talks to in Slack or the dashboard, reachable from your product, your scripts, or your backend.
Authentication
An admin creates keys in the dashboard under Settings > API. A key belongs to your whole organization: one key can message any of your agents, and you pick the agent in each call. Creating a key shows two values exactly once:
at_..., the API key. Send it as a bearer token on every request:Authorization: Bearer at_.... Store it like a password; revoking it in Settings takes effect immediately.whsec_..., the signing secret. It verifies that reply callbacks really came from AgentTeams. Your software never sends it anywhere.
The same Settings page lists every agent’s ID, ready to copy into the request URL.
Quick start
Send a message and wait for the reply in the same request:
curl -X POST https://agentteams.com/api/v1/agents/AGENT_ID/messages \
-H "Authorization: Bearer at_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"text": "A customer asks whether annual billing is available. Draft a reply.",
"conversation_id": "email-thread-8842",
"wait": 60
}'If the agent finishes within the wait window you get 200 with the reply. Otherwise you get 202 and collect the reply later via callback or polling; the agent keeps working either way.
Send a message
POST https://agentteams.com/api/v1/agents/{agentId}/messagesRequest fields:
text(required): the message for the agent, up to 100,000 characters. For long documents, attach a file instead of inlining the content.conversation_id: which conversation this message continues. Messages with the same value form one thread, and the agent remembers the whole thread, exactly like a chat channel. Use one id per email thread, ticket, or user session. Defaults todefault.event: a short name for the kind of call, likesupport-emailororder-created(lowercase letters, digits, dots, underscores, hyphens). Events give each feature its own switch and instructions in the dashboard; see Events. Defaults tomessage.event_description: a short human-readable sentence about the event (up to 300 characters), like “Fires when a customer places an order”. Shown wherever the event is listed in the dashboard, exactly like the descriptions on built-in events. Stored on the first call; if you send a different value later, the dashboard text updates.wait: how many seconds to hold the request open for a synchronous reply, up to 120. Defaults to 60, or to 0 when acallback_urlis set.callback_url: a public https URL that receives the reply when the agent finishes. Recommended for event-driven callers such as answering emails.images: up to 5 images, about 6 MB each. Each entry is exactly{ "data": "<base64>", "mediaType": "image/png" }(image/png,image/jpeg,image/gif, orimage/webp). The agent sees them.files: up to 10 files, about 15 MB each. Each entry is exactly{ "data": "<base64>", "fileName": "quote.pdf", "mediaType": "application/pdf" }withmediaTypeoptional but recommended. PDF, Word, Excel, CSV, text, and source files are read; audio is transcribed. The agent treats the content as reference material for its reply.datais plain base64 in both cases. A fulldata:...;base64,URL is accepted too (the prefix is stripped), but plain base64 is the documented form.
A finished turn returns 200:
{
"id": "9de2341c-ada6-4c38-91fa-2bc3f32de9cb",
"object": "message",
"status": "completed",
"conversation_id": "email-thread-8842",
"agent_id": "AGENT_ID",
"reply": "Hi Maria, yes, we offer annual billing with two months free...",
"created_at": "2026-08-14T09:00:00.000Z",
"completed_at": "2026-08-14T09:00:12.000Z"
}A turn that is still running when the wait window closes returns 202 with "status": "processing" and "reply": null. status is always one of completed, processing, or failed; failed messages carry a short error description.
Reply callbacks
When a message carries a callback_url, the finished reply is POSTed there, even if it takes minutes. Agents can use tools, look things up, or wait for an internal approval before answering, so callbacks are the reliable path for anything event-driven.
{
"id": "9de2341c-ada6-4c38-91fa-2bc3f32de9cb",
"object": "message",
"conversation_id": "email-thread-8842",
"agent_id": "AGENT_ID",
"status": "completed",
"reply": "Hi Maria, yes, we offer annual billing with two months free...",
"error": null,
"created_at": "2026-08-14T09:00:00.000Z",
"completed_at": "2026-08-14T09:00:12.000Z"
}Every delivery is signed. The X-Webhook-Signature header carries an HMAC-SHA256 of the raw request body, keyed with your signing secret, and X-Delivery-Attempt counts attempts. Verify before trusting the payload:
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody must be the exact bytes of the request body, before JSON parsing.
const expected =
"sha256=" +
createHmac("sha256", process.env.AGENTTEAMS_CALLBACK_SECRET)
.update(rawBody)
.digest("hex");
const signature = req.headers["x-webhook-signature"];
const valid =
signature.length === expected.length &&
timingSafeEqual(Buffer.from(expected), Buffer.from(signature));Respond with any 2xx within 15 seconds. Failed deliveries are retried with growing delays (30 seconds, then 2, 10, and 30 minutes, then 2 hours) before the delivery is marked failed.
Polling
GET https://agentteams.com/api/v1/messages/{id}Fetch any message you sent, with the same bearer key. Returns the same shape as above: 202 while processing, 200 once completed or failed. A key can only read messages it created.
Idempotency
Send an Idempotency-Key header (up to 200 characters) with a value unique per inbound event on your side. If the same key and value arrive again, you get the original message back instead of the agent running twice. Recommended whenever your caller retries, which most mail and webhook systems do.
Events
Every message belongs to an event, named by the optional event field. You never register events up front. The first call for a new event just works, and the event appears in the dashboard on its own. From there, admins get optional control:
- Discovered. A new event shows up under Settings > API with a “New” badge. Calls flow normally; nothing blocks your integration.
- Approved. One click promotes the event onto the agent’s task board, where per-event instructions can be added, for example “always answer in German”. Instructions apply to every later call for that event.
- Turned off. Calls for a disabled event are rejected with
403and codeevent_disabled, so your software sees it explicitly instead of messages silently disappearing.
Use one event name per feature to give each its own switch and instructions, and send event_description so admins see what each event means at a glance. An organization can have up to 100 active event types.
Attachments
Attachments work like on every other channel your agents use. Images are seen; documents are read; audio is transcribed. Example:
{
"text": "Summarize the attached invoice for the customer.",
"conversation_id": "email-thread-8842",
"files": [
{
"data": "<base64-encoded file content>",
"fileName": "invoice.pdf",
"mediaType": "application/pdf"
}
],
"images": [
{ "data": "<base64-encoded image>", "mediaType": "image/png" }
]
}Errors
Errors return a JSON body with error (a readable message) and code (a stable identifier):
400invalid_request: The request body failed validation. The error message names the field.400invalid_callback_url: The callback URL is not public https, or points at a private address.400event_limit: Your organization already has 100 active event types. Reuse existing event names.401unauthorized: The key is missing, malformed, or revoked.403event_disabled: This event was turned off in AgentTeams. Turn it back on under Settings, then retry.404not_found: Unknown agent or message id for this key.422attachment_processing_failed: One of the attached files could not be read.429rate_limited: More than 60 messages in a minute on one key. Back off and retry.
Rate limit: 60 messages per minute per key.
Get started
Create a key under Settings > API in your dashboard, copy an agent ID from the same page, and send your first message with the quick start above. Not sure when to use the API versus a direct tool connection? If AgentTeams already connects to the tool, connect it directly; the API is for software we don’t connect to, like your own product.
Still stuck? Get in touch and a human will write back.