Use the REST API v1
Create an API key, authenticate requests, call agents, and use the generated OpenAPI reference.
The REST API automates agents, sources, channels, actions, conversations (including operator notes), analytics, Inbox, and chat. API access is included on every plan, the free plan too; the plan sets the rate limit.
Create a key
Open workspace API Keys. Create a key with the minimum read or write scopes that you need. Copy the key immediately. Store the key as a server-side secret. Do not expose the key in browser code.
Make a request
All endpoints use this base URL:
https://www.agentstack.build/api/v1Pass the key as a bearer token:
curl https://www.agentstack.build/api/v1/agents \
-H "Authorization: Bearer $AGENTSTACK_API_KEY"The API key determines the organization. Every response uses a consistent envelope with success, data, and error fields.
Chat with an agent
curl https://www.agentstack.build/api/v1/chat \
-X POST \
-H "Authorization: Bearer $AGENTSTACK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agentId":"YOUR_AGENT_ID","message":"What is your return policy?"}'An API key needs the write scope for chat. An OAuth access token needs the mcp:chat scope (see below).
If your client can consume a streaming response, use POST /chat/stream. Reuse the conversation or session identifier that the response schema returns. Do not invent your own identifiers.
Find endpoints and schemas
The generated OpenAPI 3.1 document is the complete reference for current paths, request bodies, and response schemas. It includes agents, sources and ingestion, channels, actions, activity, analytics, topics, webhooks, contacts, conversations (GET/POST /agents/{id}/conversations/{conversationId}/notes, PATCH/DELETE /conversations/notes/{noteId}), chat, custom roles, Inbox, and messages.
Conversation notes are free-form, operator-only annotations on a chat session. The end customer never sees them. A note is useful for tagging a transcript for later review, or as training data. If the organization has webhooks configured, a new note fires a conversation.note_created webhook event.
OAuth discovery (MCP clients)
The REST API above authenticates with an API key. The MCP server uses OAuth. The REST API also accepts an OAuth access token from this flow, in place of an API key. See OAuth access tokens for the scope each endpoint needs from a token. MCP clients discover how to authenticate by fetching two metadata documents.
| Endpoint | Contents |
|---|---|
GET /.well-known/oauth-authorization-server | RFC 8414: authorize, token, registration, and revocation endpoints |
GET /.well-known/oauth-protected-resource | RFC 9728: the resource identifier and its supported scopes |
Both documents are public. Clients do not need to authenticate to fetch them. Both are also served under /api/auth/ for clients that resolve them relative to the auth base path. Both copies emit the same JSON, including an identical scopes_supported list. See Scopes for what each scope grants. A client that supports Dynamic Client Registration registers itself at the registration_endpoint that these documents advertise. There is no key to create by hand. Registration refuses a body over 32,768 bytes with 400 invalid_request. It refuses a logo_uri, client_uri, tos_uri or policy_uri that is not an http(s) URL of at most 2,048 characters, or a metadata value that is not a JSON object of at most 4,096 characters, with 400 invalid_client_metadata.
A client revokes a token it holds by sending a POST to the revocation_endpoint, which is /api/auth/mcp/revoke (RFC 7009). The body is form-encoded and carries the token and an optional token_type_hint (access_token or refresh_token). The client authenticates the same way it does at the token endpoint: with HTTP Basic, with client_id and client_secret in the body, or with client_id alone for a public client. The server answers 200 with an empty body whether or not the token existed. A client can only revoke tokens that were issued to it. Revoking either an access token or a refresh token revokes every token that the client holds for that user. This includes the refresh tokens from earlier refreshes, so the client cannot get a new access token without the user authorizing it again. AgentStack does not record which authorization a token came from. If the same user connected the same client more than once, revoking a token from one connection revokes all of them. Revocation does not forget what the user approved: if the user is signed in and the client asks again for the same scopes or fewer, the authorization completes without the consent screen.
The MCP endpoint resolves the organization in this order: the user's pinned MCP organization (set by switch_organization), then the most recent dashboard organization, then the oldest membership. If a membership is later revoked, the system discards the pin and resolves the organization again automatically. So a user who loses access to one organization does not lose the MCP connector. A REST call made with an OAuth token uses the same organization as the MCP endpoint.
Vercel Connect
AgentStack works as a Vercel Connect provider. Register the connector in Vercel. Vercel discovers the endpoints from the metadata documents above and registers itself as an OAuth client. After a user approves the connector, Vercel holds one access token. Use that token for the MCP server at https://www.agentstack.build/api/mcp, or for the REST API at https://www.agentstack.build/api/v1, with the header Authorization: Bearer <access token>. To chat with an agent through POST /chat or POST /chat/stream, the connector must request the mcp:chat scope, which the user approves on the consent screen; it is not part of the default grant. Both work on every plan, the free plan too.
Agent list fields
GET /agents returns pendingDeleteAt on each agent. This field gives the deadline for restoring an agent scheduled for deletion, or null for a live agent. The /agents endpoint returns live agents only, so the field is always null there. The MCP list_agents tool can filter to soft-deleted agents, so the field carries a value there.
Handle errors and limits
401: key is missing, invalid, or expired. For an OAuth token, the code isINVALID_ACCESS_TOKEN.403: the plan or key scope does not permit the operation.429: respectRetry-Afterand the rate-limit headers before retrying.- Validation errors return
400with a machine-readable error code and message.
Rate limits are enforced on the server side, per key and per IP, as described here.
If you suspect that a key leaked, rotate it from API Keys. For interactive administration from an AI coding client, use the MCP server instead.