A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Front API is how an app or AI agent works with a shared inbox: reading and updating conversations, sending a reply, adding an internal comment for teammates, and managing contacts, tags, and channels. Access is granted through a Bearer token, either an API token or an OAuth grant, whose namespace and permission level set which inboxes a call can read or write. Front has no version to pin, and it can push an event to a registered webhook when something happens, like a message arriving or a conversation being assigned.
How an app or AI agent connects to Front determines what it can reach. There is a route for making calls, a route for receiving events, and a hosted server that exposes Front tools to agents, and each is governed by the token behind it and the permissions that token carries.
The Core API answers at https://api2.frontapp.com. It takes JSON request bodies, returns JSON, and pages through lists with a page_token cursor. A call authenticates with a Bearer token, either an API token created in Front's settings or an OAuth 2.0 access token.
A first-party hosted Model Context Protocol server at https://mcp.frontapp.com/mcp lets an AI agent work with Front through natural language. It is in open beta and authenticates with OAuth 2.1 and PKCE as a specific teammate, so the agent's reach matches that teammate's own permissions. It exposes tools for searching and reading conversations, sending replies, adding comments, applying tags, managing contacts, and listing inboxes, teammates, and teams.
Front POSTs a JSON event to a registered URL when something happens in an inbox, like a message arriving or a conversation being assigned. An app webhook is bundled with the integration so a customer does not configure it, and each delivery is signed with an X-Front-Signature header an HMAC over the timestamp and raw body, for verification. A separate rule-based webhook can be configured per inbox.
An API token is created in Front's settings and sent as a Bearer token. It is a JWT and carries a chosen feature (like access to Core API resources), a namespace (company-wide global resources, a shared workspace, or a teammate's private resources), and a permission level of Read, Write, Delete, or Send. Front requires partners to use OAuth instead of API tokens for integrations that act on behalf of a customer, unless granted an exception.
OAuth uses the authorization-code flow at app.frontapp.com/oauth/authorize, exchanging the code at app.frontapp.com/oauth/token with Basic auth for an access token and a refresh token. The access token lasts 60 minutes and the refresh token lasts 6 months. The authorizing user must be an administrator. Front requires OAuth for public integrations available to all customers.
The Front API is split into areas an agent can act on, like conversations, messages, comments, contacts, inboxes, channels, tags, and teammates. Each area has its own methods, and a write in some areas sends a real message to a customer or changes a shared inbox.
List, read, and update conversations, the threads that hold a shared inbox's messages, comments, assignee, status, and tags.
Send a new message, reply to a conversation, and import an existing message into an inbox.
List the internal comments on a conversation and add a new one, visible only to teammates.
List a conversation's drafts and create a draft message that a teammate can review before it is sent.
List, read, create, and update the people and companies in a Front account's shared address book.
List inboxes and read a single inbox, the shared mailboxes a team works out of.
List channels and read a single channel, the connected addresses (email, SMS, social) that send and receive messages.
List tags and create a company tag used to label and route conversations.
List teammates, read a single teammate, and update a teammate's profile and availability.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
ConversationsList, read, and update conversations, the threads that hold a shared inbox's messages, comments, assignee, status, and tags.3 | ||||||
| GET | /conversations | List the conversations in the account, filterable with a search query. | read | conversations:read | Current | |
Read-only. With an OAuth token, the scopes are coarse; the underlying access is set by the token's namespace, like a single shared workspace or all shared resources. Acts onconversation Permission (capability) conversations:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /conversations/{conversation_id} | Fetch a single conversation, including its assignee, recipient, tags, and custom fields. | read | conversations:read | Current | |
Read-only. Returns 301 if the conversation has been merged into another. Acts onconversation Permission (capability) conversations:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /conversations/{conversation_id} | Update a conversation's assignee, status, or tags. | write | conversations:write | Current | |
Changing the assignee here can fire the assignee_changed application webhook. Acts onconversation Permission (capability) conversations:writeVersionAvailable since the API’s base version Webhook event assignee_changedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
MessagesSend a new message, reply to a conversation, and import an existing message into an inbox.3 | ||||||
| POST | /channels/{channel_id}/messages | Send a new outbound message from a channel, starting a conversation. | write | messages:send | Current | |
Sends a real message to a recipient and fires the outbound_sent application webhook. Acts onmessage Permission (capability) messages:sendVersionAvailable since the API’s base version Webhook event outbound_sentRate limit5 requests per channel per second SourceOfficial documentation ↗ | ||||||
| POST | /conversations/{conversation_id}/messages | Reply to a conversation, appending an outbound message to the thread. | write | messages:send | Current | |
Sends a real reply to the conversation's recipients. Acts onmessage Permission (capability) messages:sendVersionAvailable since the API’s base version Webhook event outbound_sentRate limit5 requests per conversation per second SourceOfficial documentation ↗ | ||||||
| POST | /inboxes/{inbox_id}/imported_messages | Import an existing message into an inbox without sending it to anyone. | write | messages:send | Current | |
Records a message in Front; it is not delivered to a recipient. Acts onmessage Permission (capability) messages:sendVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CommentsList the internal comments on a conversation and add a new one, visible only to teammates.2 | ||||||
| GET | /conversations/{conversation_id}/comments | List the internal comments on a conversation, newest first. | read | comments:read | Current | |
Read-only. Comments are internal and never sent to the customer. Acts oncomment Permission (capability) comments:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /conversations/{conversation_id}/comments | Add an internal comment to a conversation, visible only to teammates. | write | comments:write | Current | |
Posts a teammate-only note and fires the new_comment_added application webhook. Acts oncomment Permission (capability) comments:writeVersionAvailable since the API’s base version Webhook event new_comment_addedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
DraftsList a conversation's drafts and create a draft message that a teammate can review before it is sent.2 | ||||||
| GET | /conversations/{conversation_id}/drafts | List the drafts in a conversation. | read | drafts:read | Current | |
Read-only. A draft is an unsent message awaiting review. Acts ondraft Permission (capability) drafts:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /channels/{channel_id}/drafts | Create a draft as the first message of a new conversation, for a teammate to review. | write | drafts:write | Current | |
Creates an unsent draft; nothing is delivered until a teammate sends it. Acts ondraft Permission (capability) drafts:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ContactsList, read, create, and update the people and companies in a Front account's shared address book.4 | ||||||
| GET | /contacts | List the contacts in the account's shared address book. | read | contacts:read | Current | |
Read-only. Acts oncontact Permission (capability) contacts:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /contacts/{contact_id} | Fetch a single contact by ID or by a source-and-handle alias. | read | contacts:read | Current | |
Read-only. Acts oncontact Permission (capability) contacts:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /contacts | Create a contact with one or more handles, like an email address or phone number. | write | contacts:write | Current | |
Handles are required; a contact is shared across the company. Acts oncontact Permission (capability) contacts:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /contacts/{contact_id} | Update a contact's name, description, handles, or custom fields. | write | contacts:write | Current | |
The contact ID can be a source-and-handle alias. Acts oncontact Permission (capability) contacts:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
InboxesList inboxes and read a single inbox, the shared mailboxes a team works out of.2 | ||||||
| GET | /inboxes | List the inboxes in the account. | read | inboxes:read | Current | |
Read-only. Acts oninbox Permission (capability) inboxes:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /inboxes/{inbox_id} | Fetch a single inbox by ID. | read | inboxes:read | Current | |
Read-only. Acts oninbox Permission (capability) inboxes:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ChannelsList channels and read a single channel, the connected addresses (email, SMS, social) that send and receive messages.2 | ||||||
| GET | /channels | List the channels in the account, the connected addresses that send and receive messages. | read | channels:read | Current | |
Read-only. A channel can be email, SMS, or a social or chat integration. Acts onchannel Permission (capability) channels:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /channels/{channel_id} | Fetch a single channel by ID or by its address as an alias. | read | channels:read | Current | |
Read-only. Acts onchannel Permission (capability) channels:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TagsList tags and create a company tag used to label and route conversations.2 | ||||||
| GET | /tags | List the tags accessible to the token, including company, team, and teammate tags. | read | tags:read | Current | |
Read-only. Acts ontag Permission (capability) tags:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /company/tags | Create a company tag used to label and route conversations across the account. | write | tags:write | Current | |
A company tag is visible to the whole company; a name is required. Acts ontag Permission (capability) tags:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TeammatesList teammates, read a single teammate, and update a teammate's profile and availability.3 | ||||||
| GET | /teammates | List the teammates in the company. | read | teammates:read | Current | |
Read-only. Acts onteammate Permission (capability) teammates:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /teammates/{teammate_id} | Fetch a single teammate by ID or by email as an alias. | read | teammates:read | Current | |
Read-only. Acts onteammate Permission (capability) teammates:readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /teammates/{teammate_id} | Update a teammate's username, name, availability, or custom fields. | write | teammates:write | Current | |
Returns 204 No Content on success; the ID can be an email alias. Acts onteammate Permission (capability) teammates:writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Front can notify an app when something happens in a shared inbox, like a new message arriving or a conversation being assigned. It posts a JSON event to a registered URL, so an integration learns about activity without polling.
| Event | What it signals | Triggered by |
|---|---|---|
inbound_received | A new inbound message arrived in a connected inbox. | In-app only |
outbound_sent | An outbound message was sent from a channel, for example a reply to a customer. | /channels/{channel_id}/messages/conversations/{conversation_id}/messages |
message_delivery_failed | An outbound message failed to deliver. | In-app only |
assignee_changed | A conversation's assignee changed, including being assigned or unassigned. | /conversations/{conversation_id} |
new_comment_added | A new internal comment was added to a conversation. | /conversations/{conversation_id}/comments |
conversation_archived | A conversation was archived, closing it in the inbox. | In-app only |
conversation_reopened | A previously archived conversation was reopened. | In-app only |
conversation_moved | A conversation was moved to a different inbox. | In-app only |
tag_added | A tag was added to a conversation. | In-app only |
tag_removed | A tag was removed from a conversation. | In-app only |
Front limits how fast an app can call, by a per-minute request rate set by the company's plan, with a short burst allowance on top and a few endpoints held to tighter per-resource limits.
Front meters requests per minute per company, set by the plan: 50 on Starter, 100 on Professional, and 200 on Enterprise; a partner integration calling through OAuth gets 120 per minute, enforced per company and separate from the customer's own limit. A burst allowance of 50 percent of the plan limit absorbs short spikes and refills over a 10-minute window. A few endpoints are held tighter: analytics export and report creation allow 1 request per second, message and conversation sends allow 5 per resource per second, marking a message as seen allows 10 per message per hour, and conversation search is capped at 40 percent of the company's limit. Going over returns HTTP 429 with a retry-after header giving the seconds to wait.
List endpoints are cursor-based. A response includes a _pagination object whose next field is a full URL to the following page, and a page_token query parameter fetches it; the limit parameter sets page size up to a maximum of 100. Results come back in reverse-chronological order. Following the next URL rather than building it by hand is the supported approach.
A list page returns at most 100 results, the maximum value of limit. A company tag name is capped at 64 characters. Individual resources carry their own field limits, documented per endpoint.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | bad_request | The request was malformed, for example a missing or invalid parameter in the body or query. | Read the error message, correct the request, and resend. The request is not retryable as-is. |
| 401 | unauthorized | No valid token was provided, or the token has expired. | Send a valid Bearer token; for OAuth, refresh the access token, since it expires after 60 minutes. |
| 403 | forbidden | The token is valid but lacks the permission or namespace for this resource, for example a token scoped to one workspace reaching another. | Grant the needed permission or namespace on the token, or use a token with the right access. |
| 404 | not_found | The requested resource does not exist, or is not visible to this token. | Verify the resource ID and confirm the token can reach it. |
| 409 | conflict | The request conflicts with the current state of the resource. | Refetch the current state, then retry once the conflict is resolved. |
| 422 | unprocessable_entity | The request was well-formed but a field is invalid, for example a value that fails validation. | Correct the named field and resend. |
| 429 | too_many_requests | The per-minute rate limit or a per-resource limit was exceeded. | Wait for the seconds in the retry-after header, then retry. The x-ratelimit headers report the remaining budget. |
| 500 | server_error | An error on Front's side. It is rare. | Retry with backoff, and contact Front support if it persists. |
Front's Core API has no dated version string, so there is a single continuously updated API. Notable changes ship through the API news and updates feed rather than a version number an integration pins.
The Front Core API has no dated version string and is not pinned by the caller. Notable changes ship through the API news and updates feed, and recent additions include a first-party MCP server in open beta, granular Read, Write, and Delete permissions for API tokens, and a Core API analytics dashboard for monitoring request and rate-limit usage.
Front replaced the contact group endpoints with contact list endpoints, deprecating the contact_groups path in favor of contact_lists. Integrations that organized contacts by group needed to move to the new path.
There is no version to pin; track the API news feed for changes.
Front API news & updates ↗Bollard AI sits between a team's AI agents and Front. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.