Connect a custom agent

Connect your own external AI agent to monday.com so it can be @mentioned, assigned to items, and act on boards under its own identity.

A custom agent is an external AI agent that you own and host. Once connected, it gets its own monday.com identity, can be @mentioned in updates or assigned to items, and acts on boards through the monday.com API.

When the agent is triggered, monday.com sends a signed HTTP POST to a callback URL you provide and waits for your reply on that same request. Your service can also act on monday.com independently using an API token issued at connection time.

🚧

This feature is in alpha and under active development as of June 2026. Breaking changes are expected before general availability. All requests require the request header api-version: dev.

📘

The GraphQL mutations referenced here (connect_external_agent_sync, update_custom_agent, disconnect_external_agent, add_agent_resource_access) are documented in full on the Agents API reference.


Step 1. Create the agent

From the UI: go to Agents → Manage agents → Bring your agent, choose Custom agent, enter a name, and optionally provide a Callback URL. On the success modal, copy the API Token and Signing Secret — they are shown only once.

From the API: call connect_external_agent_sync. It returns the agent_id, signing_secret, and api_token.

📘

The callback URL is optional. Provide one if you want monday.com to notify your service when the agent is triggered. If you omit it, the agent is still created and you receive an API token — drive it through the monday.com API using that token; you just won't receive webhook events.

❗️

signing_secret and api_token are returned only once and are never shown or logged again. Store them immediately in a secrets manager. If lost, disconnect and reconnect the agent to generate new credentials.


Step 2. Receive the trigger webhook

When the agent is triggered, monday.com sends a signed POST to your callback URL.

Request body:

{
  "event": "agent_triggered",
  "triggerType": "mention",
  "payload": {
    "text": "<trigger text>",
    "...": "trigger-specific fields"
  },
  "timestamp": "2026-06-15T10:30:00Z"
}
FieldValuesDescription
eventagent_triggeredAlways agent_triggered for custom agent webhooks.
triggerTypemention, assign, unknownHow the agent was triggered.
payload.textstringThe text that triggered the agent (e.g. the @mention body).
timestampISO 8601 stringWhen the event occurred.

Request headers:

HeaderDescription
x-monday-signaturesha256=<hex> — HMAC-SHA256 signature of the request.
x-monday-timestampEpoch milliseconds — when monday.com sent the request.
x-monday-agent-idThe agent ID that triggered the event.
content-typeapplication/json

Step 3. Reply to the webhook

The webhook is synchronous — think of it as a phone call, not a text message. monday.com holds the request open and waits; you reply in the HTTP response to that same request. There is no separate reply token or reply URL.

How it works: monday.com makes a single POST to your callback URL with a 30-second timeout attached to that request. Your reply is whatever you return on that connection. When monday.com receives your response it reads the body (the JSON message, or the streamed SSE text) and uses it as the agent's reply. If the 30 seconds elapse before you've finished responding, monday.com aborts the connection and the run fails with a timeout — there's no way to reply to that trigger afterward. The response body is capped at 1 MB.

The whole window — including a full SSE stream — must complete within those 30 seconds.

Reply in one of two ways:

JSON — a single response:

{ "success": true, "message": "Your reply text" }

Server-Sent Events (SSE) — stream the reply as it's generated. Set content-type: text/event-stream and emit data: lines:

data: {"type":"text","content":"Partial "}
data: {"type":"text","content":"reply text"}
data: {"type":"done","success":true}
🚧

If you don't respond within 30 seconds, the run fails with a timeout — you cannot reply to that trigger afterward. For longer work, acknowledge quickly and act asynchronously using the agent's API token (see Act on monday.com).


Step 4. Verify the webhook signature

Every incoming webhook must be verified before processing. Use constant-time comparison to prevent timing attacks.

  1. Read x-monday-signature and x-monday-timestamp from the request headers.
  2. Compute HMAC-SHA256(signing_secret, "{x-monday-timestamp}.{raw_body}").
  3. Prefix your result with sha256= and compare it to x-monday-signature using a constant-time comparison.
  4. Reject requests where signatures don't match or the timestamp is stale.
const crypto = require('crypto');

function verifySignature(signingSecret, rawBody, headers) {
  const timestamp = headers['x-monday-timestamp'];
  const receivedSig = headers['x-monday-signature'];

  if (!timestamp || !receivedSig) return false;

  const expected = 'sha256=' + crypto
    .createHmac('sha256', signingSecret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');

  // timingSafeEqual throws if the buffers differ in length, so guard first.
  const expectedBuf = Buffer.from(expected);
  const receivedBuf = Buffer.from(receivedSig);
  return (
    expectedBuf.length === receivedBuf.length &&
    crypto.timingSafeEqual(expectedBuf, receivedBuf)
  );
}
🚧

The callback_url must be a valid HTTPS URL reachable from monday.com's infrastructure. It is re-validated at execution time as a protection against SSRF and DNS-rebinding attacks.


Step 5. Act on monday.com

Connected agents act under their own monday.com identity — your own account access does not carry over to the agent. Grant the agent access to the boards or docs it needs (the agent's page → Knowledge and access, or the add_agent_resource_access mutation), then call the API with the agent's api_token:

curl -X POST https://api.monday.com/v2 \
  -H "Authorization: <agent-api-token>" \
  -H "Content-Type: application/json" \
  -d '{"query": "{ me { id name } }"}'

The api_token is long-lived — it does not expire on a timer and is only revoked when the agent is disconnected. Use it for work that outlasts the 30-second webhook window.


Manage the agent

  • Update the name or callback URL — update_custom_agent (owner token with agent_id, or the agent's own api_token with agent_id omitted). Changing callback_url rotates signing_secret — persist the new value.
  • Disconnect — disconnect_external_agent. This revokes the agent's token and deletes the agent.

Troubleshooting

The agent says it has access but can't edit items.
The agent acts under its own identity. Grant READ_WRITE access to the relevant board (see Step 5) — your own board access has no effect on the agent.

Webhook signature verification is failing.
Compute HMAC-SHA256 over "{x-monday-timestamp}.{raw_body}" using the signing_secret (not the API token), and use the raw, unparsed request body.

The webhook times out.
You must respond within 30 seconds. For longer work, reply quickly and continue asynchronously using the agent's API token.

The secrets were lost after setup.
signing_secret and api_token are shown only once. If lost, disconnect the agent and reconnect to generate new credentials.


📘

Join our developer community!

If you have questions or need help with custom agents, visit the monday.com developer community.


Did this page help you?