Skip to content
HelpThe AgentTeams API

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}/messages

Request 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 to default.
  • event: a short name for the kind of call, like support-email or order-created (lowercase letters, digits, dots, underscores, hyphens). Events give each feature its own switch and instructions in the dashboard; see Events. Defaults to message.
  • 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 a callback_url is 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, or image/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" } with mediaType optional 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.
  • data is plain base64 in both cases. A full data:...;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 403 and code event_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):

  • 400 invalid_request: The request body failed validation. The error message names the field.
  • 400 invalid_callback_url: The callback URL is not public https, or points at a private address.
  • 400 event_limit: Your organization already has 100 active event types. Reuse existing event names.
  • 401 unauthorized: The key is missing, malformed, or revoked.
  • 403 event_disabled: This event was turned off in AgentTeams. Turn it back on under Settings, then retry.
  • 404 not_found: Unknown agent or message id for this key.
  • 422 attachment_processing_failed: One of the attached files could not be read.
  • 429 rate_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.