Learn how to read, create, configure, run, and connect AI agents using the platform API
Pre-release feature. The agents API is currently available only in the
dev(pre-release) API version. It is not included in any dated API version yet (including2026-10). Signatures, types, and behavior can still change before this lands in a dated version. Send requests with theAPI-Version: devheader to use it.
monday.com agents are AI work orchestrators that can be triggered to perform automated actions on monday.com boards, items, and updates. An agent has a profile (name, role, avatar), a goal, an execution plan, an optional set of skills, knowledge resources (boards and docs it can access), and triggers that start its runs. For an overview of the agent model and how to connect external agents, see Build on monday.com with AI.
There are three kinds of agent:
- Personal — owned by a specific user and created from a prompt or built blank.
- Account-level — available to the entire account.
- External — brought into monday.com from an external provider (managed providers like a Claude-managed agent, or a custom agent reachable via a callback URL). See Connect external agents.
Newly created agents start in the INACTIVE state and cannot be triggered until activated.
Queries
Get agents
- Returns an array of
Agentobjects - Can be queried directly at the root
- Deleted agents are not returned
query {
agents(ids: [1234567890], limit: 25) {
id
kind
state
agent_model
version_id
profile {
name
role
role_description
avatar_url
}
plan
skill_ids
created_at
updated_at
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| ids | [ID!] | The specific agent IDs to return. Omit to return all agents. |
| limit | Int | The maximum number of agents to return. |
Fields
The query returns Agent objects. See the other types page for the full field list.
Get agent knowledge
- Returns an
AgentKnowledgeobject - The full knowledge configuration of an agent: resources (boards and docs) and uploaded files
query {
agent_knowledge(id: 1234567890) {
resources {
resource_id
scope_type
permission_type
}
files {
id
file_name
file_type
}
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| id | ID! | The agent's unique identifier. |
Get agent triggers catalog
- Returns an array of
AgentTriggerCatalogEntryobjects - Browse the available trigger types you can attach to an agent with
add_trigger_to_agent
query {
agent_triggers_catalog {
block_reference_id
name
description
required_fields {
field_key
depends_on
optional
}
field_schemas {
field_key
value_schema
}
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| block_reference_ids | [ID!] | Filter the catalog to specific trigger types by their IDs. |
Get an agent's active triggers
- Returns an array of
AgentActiveTriggerobjects - The triggers currently attached to an agent
query {
agent_active_triggers(agent_id: 1234567890) {
node_id
block_reference_id
name
description
field_summary
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| agent_id | ID! | The agent's unique identifier. |
Get agent skills catalog
- Returns an array of
AgentSkillCatalogEntryobjects - Browse the skills you can attach to an agent with
add_skill_to_agent
query {
agent_skills_catalog {
id
name
description
}
}Get external provider agents
- Returns an array of
ProviderResourceobjects - Lists the agents (and other resources) available on an external provider, using a stored credential
query {
external_provider_agents(credential_id: 1234567890, provider_type: CLAUDE_MANAGED_AGENT) {
id
name
}
}Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| credential_id | ID! | The credential used to authenticate with the provider. | |
| provider_type | ExternalProvider! | The external provider to query. | CLAUDE_MANAGED_AGENT CUSTOM_AGENT OPENAI |
Mutations
Mutations run in the context of the authenticated user and are subject to that user's monday.com permissions. Newly created agents are returned in the
INACTIVEstate and must be activated before they can run.
Create an agent
Creates a personal agent from a prompt. The platform uses AI to generate the agent's profile, goal, and execution plan from your description. Returns an Agent.
created_atandupdated_atarenullin the creation response. Call theagentsquery with the returnedidto fetch the populated timestamps.
mutation {
create_agent(input: {
prompt: "Summarize open items on a board daily and post a digest as an update."
}) {
id
kind
state
profile {
name
role
}
goal
skill_ids
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| input | CreateAgentInput! | The prompt and optional model and knowledge files for the agent. |
Create a blank agent
Creates a personal agent without AI generation. You supply the profile fields directly. Returns an Agent.
mutation {
create_blank_agent(input: {
name: "Digest Bot",
role: "Daily Digest Manager",
role_description: "Posts a daily summary of open items",
background_color: "#9450fd"
}) {
id
kind
state
profile {
name
role
avatar_url
background_color
}
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| input | CreateBlankAgentInput | The profile fields for the agent. Optional. |
Update an agent
Updates an agent's profile, plan, or model. All fields are optional; only the fields you provide are changed. Returns an Agent.
mutation {
update_agent(id: 1234567890, input: {
name: "Digest Bot",
role: "Senior Digest Manager",
plan: "## Plan\n1. Read open items.\n2. Post a daily digest update.",
agent_model: CLAUDE_SONNET_4_6
}) {
id
version_id
profile {
name
role
}
plan
agent_model
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| id | ID! | The agent's unique identifier. |
| input | UpdateAgentInput! | The fields to update on the agent. |
Delete an agent
Permanently deletes an agent. Returns the deleted Agent with its state set to DELETED. Deleted agents are no longer returned by the agents query.
mutation {
delete_agent(id: 1234567890) {
id
state
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| id | ID! | The agent's unique identifier. |
Activate an agent
Activates an agent so it can be triggered and run. Returns an AgentStateResult.
mutation {
activate_agent(id: 1234567890) {
success
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| id | ID! | The agent's unique identifier. |
Deactivate an agent
Deactivates an agent so it can no longer be triggered. Returns an AgentStateResult.
mutation {
deactivate_agent(id: 1234567890, inactive_reason: DEACTIVATED_BY_USER) {
success
}
}Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| id | ID! | The agent's unique identifier. | |
| inactive_reason | InactiveReason | The reason the agent is being deactivated. | ACCOUNT_LEVEL_BLOCKING DEACTIVATED_BY_USER RUNS_RATE_LIMIT_EXCEEDED |
Run an agent
Manually triggers an agent run. The agent must be ACTIVE. The run executes asynchronously — the response only confirms that the run was accepted and enqueued, not its outcome. Returns a RunAgentResult.
mutation {
run_agent(id: 1234567890) {
trigger_uuid
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| id | ID! | The agent's unique identifier. |
Add a trigger to an agent
Attaches a trigger to an agent. Use agent_triggers_catalog to find the block_reference_id and the fields each trigger requires. Returns a MutationResult.
mutation {
add_trigger_to_agent(
agent_id: 1234567890,
block_reference_id: 10380130,
field_values: { boardId: { value: "9876543210", label: "My board" } }
) {
success
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| agent_id | ID! | The agent's unique identifier. |
| block_reference_id | ID! | The trigger type to attach, from agent_triggers_catalog. |
| field_values | JSON | The trigger configuration. Provide required_fields as { value, label } pairs and field_schemas fields in the documented JSON shape. |
Remove a trigger from an agent
Detaches a trigger from an agent. Use agent_active_triggers to find the node_id of the trigger instance. Returns a MutationResult.
mutation {
remove_trigger_from_agent(agent_id: 1234567890, node_id: 1) {
success
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| agent_id | ID! | The agent's unique identifier. |
| node_id | ID! | The trigger instance to remove, from agent_active_triggers. |
Create an agent skill
Creates a reusable skill in the account's skills catalog. Returns an AgentSkillCatalogEntry.
mutation {
create_agent_skill(
name: "Echo",
content: "When asked, echo the input back verbatim.",
description: "A simple echo skill"
) {
id
name
description
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| name | String! | The display name of the skill. |
| content | String! | The instructions that define what the skill does. |
| description | String | A short description of the skill. |
Add a skill to an agent
Attaches a skill from the catalog to an agent. Use agent_skills_catalog to find the skill_id. Returns a MutationResult.
mutation {
add_skill_to_agent(agent_id: 1234567890, skill_id: 9876543210) {
success
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| agent_id | ID! | The agent's unique identifier. |
| skill_id | ID! | The skill to attach, from agent_skills_catalog. |
Remove a skill from an agent
Detaches a skill from an agent. Returns a MutationResult.
mutation {
remove_skill_from_agent(agent_id: 1234567890, skill_id: 9876543210) {
success
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| agent_id | ID! | The agent's unique identifier. |
| skill_id | ID! | The skill's unique identifier. |
Add resource access to an agent
Grants an agent access to a monday.com board or doc as knowledge. Returns a MutationResult.
mutation {
add_agent_resource_access(
id: 1234567890,
resource_id: 9876543210,
scope_type: BOARD,
permission_type: READ_WRITE
) {
success
}
}Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| id | ID! | The agent's unique identifier. | |
| resource_id | ID! | The ID of the board or doc to grant access to. | |
| scope_type | KnowledgeScope! | Whether the resource is a board or a doc. | BOARD DOC |
| permission_type | KnowledgePermission! | The permission level to grant. | READ READ_WRITE |
Update resource access for an agent
Changes the permission level an agent has on a resource it already has access to. Returns a MutationResult.
mutation {
update_agent_resource_access(
id: 1234567890,
resource_id: 9876543210,
scope_type: BOARD,
permission_type: READ
) {
success
}
}Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| id | ID! | The agent's unique identifier. | |
| resource_id | ID! | The ID of the board or doc. | |
| scope_type | KnowledgeScope! | Whether the resource is a board or a doc. | BOARD DOC |
| permission_type | KnowledgePermission! | The new permission level. | READ READ_WRITE |
Remove resource access from an agent
Revokes an agent's access to a resource. Returns a MutationResult.
mutation {
remove_agent_resource_access(
id: 1234567890,
resource_id: 9876543210,
scope_type: BOARD
) {
success
}
}Arguments
| Argument | Type | Description | Enum Values |
|---|---|---|---|
| id | ID! | The agent's unique identifier. | |
| resource_id | ID! | The ID of the board or doc. | |
| scope_type | KnowledgeScope! | Whether the resource is a board or a doc. | BOARD DOC |
Connect external agents
You can bring your own agent into monday.com as a first-class participant. Connected agents authenticate with their own API token and operate within the permission scope granted by the account admin. They can be assigned to items, mentioned in updates, and consume AI credits tracked under the account's usage dashboard. See Build on monday.com with AI for the conceptual overview.
There are two connection paths:
- Managed provider (e.g. a Claude-managed agent) — monday.com orchestrates calls to the provider. Use the asynchronous
connect_external_agentmutation. - Custom agent (webhook) — you provide a callback URL that monday.com posts event payloads to. Use the synchronous
connect_external_agent_syncmutation, which returns the credentials your agent needs.
For an end-to-end walkthrough of building, hosting, and responding from a custom agent — including webhook signature verification and the SSE chat-reply format — see the Build an external agent guide.
Connect an external agent (async)
Initiates a connection to an external provider agent. This is an asynchronous operation: the response confirms the connection has started (status: "connecting"), and the final result is delivered out of band (via Pusher). Returns a ConnectExternalAgentPayload.
mutation {
connect_external_agent(input: {
external_provider_type: CLAUDE_MANAGED_AGENT,
external_agent_id: "agent-abc-123",
credential_id: 1234567890,
name: "Claude Research Agent"
}) {
status
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| input | ConnectExternalAgentInput! | The provider, agent, credential, and metadata. |
Connect a custom agent (sync)
Connects a custom external agent reachable via a callback URL and returns the credentials it needs in a single synchronous call. Returns a ConnectExternalAgentResult containing the new agent_id, a signing_secret (to verify incoming webhooks), an api_token (for the agent to call back into monday.com), and instructions.
The
signing_secretandapi_tokenare returned only once and are never logged. Store them securely. Theapi_tokenacts as the connected agent's identity — any data the agent creates with it (boards, items, updates) is attributed to the agent.
mutation {
connect_external_agent_sync(input: {
custom: {
name: "Cursor Test",
callback_url: "https://example.com/my-agent/callback"
}
}) {
agent_id
signing_secret
api_token
instructions
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| input | ConnectExternalAgentSyncInput! | Wrapper input; currently supports custom agents only. |
Update a custom agent
Updates a connected custom agent's display name or callback URL. Both fields are optional and independent — you can change one without touching the other. Returns an UpdateCustomAgentPayload.
update_custom_agentruns in the context of the agent owner's token — not the agent's ownapi_token. Using the agent token returns an authorization error.
mutation {
update_custom_agent(input: {
agent_id: 1234567890,
name: "My Renamed Agent",
callback_url: "https://your-service.example.com/new-webhook-path"
}) {
success
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| input | UpdateCustomAgentInput! | The agent ID plus the fields to change. |
The new
callback_urlmust be a valid public HTTPS URL reachable from monday.com (notlocalhostor an internal*.run.apphost). It is re-validated at execution time as protection against SSRF and DNS-rebinding attacks. Errors (agent not found, caller is not the owner, invalid URL) are returned as GraphQL errors rather thansuccess: false.
Disconnect an external agent
Disconnects a connected external agent. Returns a DisconnectExternalAgentPayload.
mutation {
disconnect_external_agent(id: 1234567890) {
success
}
}Arguments
| Argument | Type | Description |
|---|---|---|
| id | ID! | The agent's unique identifier. |
Custom agent webhooks
When a custom agent (one connected with a callback_url via connect_external_agent_sync) is triggered, monday.com sends a signed HTTP POST to that callback URL and waits for your reply on the same request. There is no separate reply token or reply URL — the request is synchronous. The chat trigger in particular has no item, board, or message IDs, so the only way to reply to it is in the HTTP response (see Respond to a trigger).
Receive a trigger
monday.com sends an HTTP POST to your callback URL whenever the agent is triggered.
Headers
| Header | Example | Description |
|---|---|---|
x-monday-agent-id | 139988 | Which agent was triggered. Use it to look up that agent's stored signing_secret and api_token. |
x-monday-signature | sha256=a3a6ce… | HMAC-SHA256 of the signed string. Verify it before processing. |
x-monday-timestamp | 1782326623754 | Epoch milliseconds. Part of the signed string. |
content-type | application/json | The request body is JSON. |
Agents hosted on monday-code (Cloud Run) also receive infrastructure headers:
x-serverless-authorization(a Google-signed JWT),host(the internal…---service-….a.run.apphost — not your public URL; do not derive your callback URL from it),x-forwarded-*,cf-*,via: 1.1 google, anduser-agent: node. Sign and route on thex-monday-*headers above, not on these.
Body envelope
The body always has the same shape; only payload varies by trigger type.
{
"event": "agent_triggered",
"triggerType": "chat",
"payload": { "text": "...", "...": "trigger-specific fields" },
"timestamp": "2026-06-24T18:43:43.754Z"
}| Field | Type | Description |
|---|---|---|
event | String | Always agent_triggered for custom agent webhooks. |
triggerType | String | How the agent was triggered: chat, assigned, mentioned, or unknown. |
payload | Object | Trigger-specific data. Always includes text; other fields depend on triggerType. |
timestamp | String | ISO 8601 time the event occurred. |
Trigger types
chat
chatThe user typed a message in the agent chat. The payload is minimal and contains no IDs:
{
"event": "agent_triggered",
"triggerType": "chat",
"payload": { "text": "sent this message through agent chat" },
"timestamp": "2026-06-24T18:43:43.754Z"
}Because there is no conversation or message ID, you cannot reply with a GraphQL API call. The reply must be returned in the HTTP response — see Respond to a trigger.
assigned
assignedThe agent was assigned to an item. The payload carries the full target, and monday.com wraps the instructions as a prompt in text:
{
"event": "agent_triggered",
"triggerType": "assigned",
"payload": {
"text": "You were assigned to an item. Follow these steps:\n1. ...\nTRIGGER DATA:\n- itemId: 12334011531\n- boardId: 18418747579\n- groupId: topics",
"itemId": 12334011531,
"boardId": 18418747579,
"groupId": "topics",
"updateId": null,
"replyId": null,
"updateBody": null,
"files": null
},
"timestamp": "2026-06-24T18:45:26.706Z"
}Because the payload includes a target (itemId, boardId), you can act on it through the GraphQL API under the agent's identity — see Act as the agent.
mention
mentionThe agent was @mentioned in an update. Like assigned, the payload carries target IDs you can act on via the API. A mention only delivers a webhook when the agent has access to the relevant board and is mentioned in a valid context.
Verify a trigger
Verify every incoming request before processing it. Compute an HMAC-SHA256 over the string {x-monday-timestamp}.{rawBody} using the agent's signing_secret (from the connect response — not the api_token), prefix the hex digest with sha256=, and compare it to x-monday-signature using a constant-time comparison.
HMAC the raw, unparsed request body bytes. If you re-serialize a parsed
req.bodythe signature will not match (capture the raw body, e.g. with anexpress.json({ verify })hook).
const expected = 'sha256=' + crypto
.createHmac('sha256', signingSecret)
.update(`${timestamp}.${rawBody}`) // raw body, not re-serialized
.digest('hex');
const ok =
expected.length === sig.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));Respond to a trigger
monday.com reads your reply synchronously from the HTTP response to the trigger request. The default reply mode is streaming (Server-Sent Events). A request can opt out by sending stream: false in its body.
Streaming (default — what chat uses): respond with 200 and Content-Type: text/event-stream, write each piece as a data: event, and terminate the stream with data: [DONE]. monday.com concatenates the content pieces into the chat message.
res.status(200);
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
for (const chunk of tokens) {
res.write(`data: ${JSON.stringify({ type: 'text', content: chunk })}\n\n`);
}
res.write('data: [DONE]\n\n');
res.end();Each event is data: {"type":"text","content":"<piece>"} followed by a blank line, and the stream ends with data: [DONE].
Non-streaming (when the request body has stream: false): return a single JSON object.
{ "message": "your full reply text" }Respond within 30 seconds, with body ≤ 1 MB and status 200 — the whole window, including a full SSE stream, must complete in time, or the run fails with a timeout and cannot be answered afterward. A plain JSON body such as
{ "text": "..." }for a chat trigger does not render and surfaces as "Something went wrong while running the agent."
Act as the agent
For triggers that carry a target (assigned, mention), do work under the agent's identity by calling the GraphQL API with the agent's api_token and the API-Version: dev header:
mutation {
create_update(item_id: 12334011531, body: "On it ✅") {
id
}
}The agent must have explicit access to the board — your own account's access does not carry over. Grant it with add_agent_resource_access:
mutation {
add_agent_resource_access(
id: 139988,
resource_id: 18418747579,
scope_type: BOARD,
permission_type: READ_WRITE
) {
success
}
}The
callback_urlmust be a public HTTPS endpoint reachable by monday.com — not the internal*.run.apphost and notlocalhost. It is re-validated at execution time as protection against SSRF. Set or change it withupdate_custom_agent(requires the owner's token, not the agent token).
