# Authentication Source: https://docs.getarbol.com/api-reference/authentication Authenticate to the organization-scoped Arbol API with the security scheme declared by OpenAPI. Send API credentials as an HTTP bearer token. ```http theme={"theme":{"light":"github-light","dark":"github-dark"}} Authorization: Bearer ``` The production OpenAPI document is authoritative for the active security schemes, issuer, token endpoint, and required scopes. Credentials are provisioned for approved organizations during onboarding. ## OAuth contract The Auth0-based contract defines two alternatives: * `userOAuth` uses the authorization-code flow for a person acting in one organization. Each operation includes the baseline `org:use` scope plus its resource permissions. * `machineOAuth` uses client credentials for an organization-bound service. Its grant must include every scope named by the operation. ## Protected-resource metadata OAuth clients can discover API resource metadata at: ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} https://api.getarbol.com/.well-known/oauth-protected-resource ``` On a `401` response, inspect the `WWW-Authenticate` header for the resource-metadata location. ## Token handling * Never put a bearer token in a query parameter. * Never forward an API token to the MCP endpoint. MCP uses its own audience and exchanges delegated authority for an API token. * Request only the scopes your integration needs. * Keep user tokens and machine credentials in separate storage and rotation policies. * Treat `401` as an invalid or unusable credential and `403` as a verified credential without sufficient authority. ## Organization machine credentials A machine integration uses an approved OAuth client and an organization-scoped client grant. It exchanges its credentials for a short-lived access token for the API audience. This is OAuth Client Credentials, not an API key that selects an organization when attached to a request. An organization parameter in a token request only selects an organization the client is already authorized to access. The API derives tenant authority from verified token claims and still enforces the operation's actor policy and scopes. Never put an organization id in a request body to switch tenants. Provisioning and credential rotation are separate from installing a client library. Store machine credentials server-side, request the least authority needed, and use the authentication flow provisioned for that specific service. Do not reuse a machine token for a person-delegated MCP connection. See Auth0's [organization machine-access documentation](https://auth0.com/docs/manage-users/organizations/organizations-for-m2m-applications). # Cancel an Agent evaluation run Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/cancel-an-agent-evaluation-run https://api.getarbol.com/openapi.json post /agents/{agentId}/evaluation-runs/{runId}/cancel Records a cancellation request under agents:read and agent-evaluations:run; running trials stop only at their durable boundary. A repeated request against a terminal run returns conflict, so inspect the returned state before retrying. # Create an Agent evaluation suite Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/create-an-agent-evaluation-suite https://api.getarbol.com/openapi.json post /agents/{agentId}/evaluation-suites Creates one suite under agent-evaluations:write; recorded and tool-bearing cases require their additional evidence permissions, mocked tools require exact fixtures, and AI rubrics must begin advisory. Use the human-only promotion operation after golden-set calibration. No idempotency key exists, so confirm an uncertain response before retrying. # Create an evaluation trace download capability Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/create-an-evaluation-trace-download-capability https://api.getarbol.com/openapi.json post /agents/{agentId}/evaluation-runs/{runId}/trials/{trialId}/artifact Under agent-evaluations:read plus permissions required by the run evidence, issues a short-lived capability only for a retained, integrity-matched private trace. It does not mutate the run, and requesting another capability is safe. # Get an Agent evaluation run Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/get-an-agent-evaluation-run https://api.getarbol.com/openapi.json get /agents/{agentId}/evaluation-runs/{runId} Returns immutable run summary state under agent-evaluations:read and no trace payloads by default. Trial expansion additionally requires conversations:transcript for recorded inputs, integrations:read for mocked tools, and knowledge:read for Knowledge evidence. It is side-effect free and safe to retry. # Get an Agent evaluation suite Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/get-an-agent-evaluation-suite https://api.getarbol.com/openapi.json get /agents/{agentId}/evaluation-suites/{suiteId} Returns one suite under agent-evaluations:read; recorded-conversation cases additionally require conversations:transcript and mocked or tool-bearing cases require integrations:read. It performs no writes and is safe to retry. # List Agent evaluation runs Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/list-agent-evaluation-runs https://api.getarbol.com/openapi.json get /agents/{agentId}/evaluation-runs Lists immutable evaluation run records for one tenant-owned Agent under agent-evaluations:read. It has no side effects and is safe to retry with the same cursor and filters. # List Agent evaluation suites Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/list-agent-evaluation-suites https://api.getarbol.com/openapi.json get /agents/{agentId}/evaluation-suites Lists suite metadata and case counts under agent-evaluations:read; case bodies and evidence require the detail operation. It performs no writes and is safe to retry with the same cursor. # Promote a calibrated AI rubric Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/promote-a-calibrated-ai-rubric https://api.getarbol.com/openapi.json post /agents/{agentId}/evaluation-suites/{suiteId}/cases/{caseId}/rubrics/{scorerKey}/promote A human actor attests a bounded golden set. The API binds that evidence to the exact rubric and current judge configuration, versions it, and records an explicit blocking promotion in the suite revision. # Replace an Agent evaluation suite Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/replace-an-agent-evaluation-suite https://api.getarbol.com/openapi.json put /agents/{agentId}/evaluation-suites/{suiteId} Updates one suite under agent-evaluations:write at expectedRevision; supplied cases replace the complete array, evidence requires additional permissions, and generic replacement cannot create or preserve a blocking AI rubric. Use the human-only promotion operation after replacement. A successful revision is consumed, so do not blindly replay an uncertain request. # Start an Agent evaluation run Source: https://docs.getarbol.com/api-reference/endpoints/agent-evaluations/start-an-agent-evaluation-run https://api.getarbol.com/openapi.json post /agents/{agentId}/evaluation-runs Under agents:read and agent-evaluations:run, snapshots the active suite, rubric calibration/promotion state, pricing policy, and current runnable Agent configuration before starting one durable run. Evidence types require their additional permissions, and stale blocking-rubric calibration fails admission. No idempotency key exists, so an uncertain retry creates a distinct run. # Create an Agent Source: https://docs.getarbol.com/api-reference/endpoints/agents/create-an-agent https://api.getarbol.com/openapi.json post /agents Creates one coherent Agent desired state under agents:write and reconciles voice provider state before reporting success; its profile, Knowledge selection, and account-qualified tool access require their additional permissions when configured. No idempotency key exists, so confirm an uncertain response before retrying. # Create an Agent Knowledge MCP session Source: https://docs.getarbol.com/api-reference/endpoints/agents/create-an-agent-knowledge-mcp-session https://api.getarbol.com/openapi.json post /agents/{agentId}/knowledge-sessions Issues a five-minute, read-only Streamable HTTP MCP capability for an active Agent in the verified Organization. Requires agents:read and knowledge:read. Use the returned token as Authorization: Bearer when calling the returned URL from an MCP client. It searches only the Agent's current assigned documents; it cannot access business tools. Treat the token as a secret. Retrying issues another temporary capability; no persistent session is created. # Delete an Agent Source: https://docs.getarbol.com/api-reference/endpoints/agents/delete-an-agent https://api.getarbol.com/openapi.json delete /agents/{id} Soft-deletes one tenant-owned Agent under agents:write, then best-effort removes its voice runtime. Repeating the request may return not found, so confirm an uncertain response before retrying. # Get an Agent Source: https://docs.getarbol.com/api-reference/endpoints/agents/get-an-agent https://api.getarbol.com/openapi.json get /agents/{id} Returns one Agent from the verified Organization under agents:read. Knowledge and tool-access expansions require their additional read permissions; the operation is side-effect free and retry-safe. # List Agents Source: https://docs.getarbol.com/api-reference/endpoints/agents/list-agents https://api.getarbol.com/openapi.json get /agents Lists Agents in the verified Organization under agents:read. It performs no writes and is safe to retry with the same cursor and filters. # Update an Agent Source: https://docs.getarbol.com/api-reference/endpoints/agents/update-an-agent https://api.getarbol.com/openapi.json patch /agents/{id} Updates the current Agent desired state under agents:write with last-write-wins fields and reconciles voice provider state before reporting success; a supplied profile, Knowledge selection, or tool access replaces that complete part and may require additional permissions. Tool access keeps its own optimistic revision. Confirm an uncertain response before retrying. # Query a fact breakdown Source: https://docs.getarbol.com/api-reference/endpoints/analytics/query-a-fact-breakdown https://api.getarbol.com/openapi.json post /analytics/fact-breakdown Counts one conversation Definition's current Fact values over conversations started in the window, under analytics:read. It performs no writes and is safe to retry with the same body. # Query analytics Source: https://docs.getarbol.com/api-reference/endpoints/analytics/query-analytics https://api.getarbol.com/openapi.json post /analytics/query Returns only the requested tenant-scoped analytics sections under analytics:read and resolves their shared time window once. It performs no writes and is safe to retry with the same body. # Query retention cohorts Source: https://docs.getarbol.com/api-reference/endpoints/analytics/query-retention-cohorts https://api.getarbol.com/openapi.json post /analytics/retention Counts weekly cohorts of first-time contacts and the later weeks they returned in, under analytics:read. It performs no writes and is safe to retry with the same body. # Assign the channel Agent Source: https://docs.getarbol.com/api-reference/endpoints/channels/assign-the-channel-agent https://api.getarbol.com/openapi.json put /channels/{channelId}/agent Attaches an Agent to a connected channel that has none, under agents:write and channels:write. It fails if the channel already has an Agent or the Agent has no live runtime for the channel kind. # Authorize the Agent channel Source: https://docs.getarbol.com/api-reference/endpoints/channels/authorize-the-agent-channel https://api.getarbol.com/openapi.json post /channels/{channelId}/authorization Issues a new short-lived setup capability for the named pending WhatsApp channel under agents:write and channels:write. It does not change the desired assignment, and requesting another capability safely supersedes the prior URL. # Create the Agent channel Source: https://docs.getarbol.com/api-reference/endpoints/channels/create-the-agent-channel https://api.getarbol.com/openapi.json post /channels Connects a carrier number, SIP trunk, or WhatsApp endpoint for the verified Organization under agents:write and channels:write. Omit agentId to connect it unassigned and attach an Agent later; several endpoints may route to the same Agent. Provider onboarding has no idempotency key, so confirm an uncertain response before retrying. # Delete the Agent channel Source: https://docs.getarbol.com/api-reference/endpoints/channels/delete-the-agent-channel https://api.getarbol.com/openapi.json delete /channels/{channelId} Disconnects and retires the named channel under agents:write and channels:write. A repeat may return not found, so confirm an uncertain response before retrying. # Get a channel Source: https://docs.getarbol.com/api-reference/endpoints/channels/get-a-channel https://api.getarbol.com/openapi.json get /channels/{channelId} Reads one connected channel of the verified Organization by its own id under agents:read and channels:read. It performs no provider writes and is safe to retry. # Get a representative Agent channel Source: https://docs.getarbol.com/api-reference/endpoints/channels/get-a-representative-agent-channel https://api.getarbol.com/openapi.json get /agents/{agentId}/channel Reads one representative provider-neutral channel of the named Agent under agents:read and channels:read. Use the organization channel list for the complete endpoint inventory. It performs no provider writes and is safe to retry. # List channels Source: https://docs.getarbol.com/api-reference/endpoints/channels/list-channels https://api.getarbol.com/openapi.json get /channels Lists every connected channel in the verified Organization under agents:read and channels:read, optionally only those assigned to one Agent. It performs no provider writes and is safe to retry with the same cursor. # Recover an existing WhatsApp channel Source: https://docs.getarbol.com/api-reference/endpoints/channels/recover-an-existing-whatsapp-channel https://api.getarbol.com/openapi.json post /channels/{channelId}/reconcile Recovers an already-connected WhatsApp number into the named channel under agents:write and channels:write. Verifies the number belongs to the authenticated Organization, requires an assigned active WhatsApp Agent, and configures the signed inbound webhook. A pending channel, including expired setup, enables inbound and outbound traffic; active/degraded retries preserve assignment and directions. Never buys a number, sends a message, or replaces an existing endpoint. Provider failure may leave the channel degraded; read it and retry the same input. Discovery is bounded to 100 numbers per provider customer and rejects incomplete inventories. # Unassign the channel Agent Source: https://docs.getarbol.com/api-reference/endpoints/channels/unassign-the-channel-agent https://api.getarbol.com/openapi.json delete /channels/{channelId}/agent Returns a connected channel to the unassigned pool under agents:write and channels:write. The provider endpoint is kept; the channel simply stops answering. # Update the Agent channel Source: https://docs.getarbol.com/api-reference/endpoints/channels/update-the-agent-channel https://api.getarbol.com/openapi.json patch /channels/{channelId} Updates direction or display settings on the named channel under agents:write and channels:write, reconciling provider state. An unassigned channel cannot enable traffic. There is no idempotency key; inspect current state before replaying an uncertain request. # Connect a Composio account Source: https://docs.getarbol.com/api-reference/endpoints/connected-accounts/connect-a-composio-account https://api.getarbol.com/openapi.json post /connected-accounts Creates a Composio Connect Link for the authenticated organization. Arbol stores no account or authorization session. # Delete a Composio account Source: https://docs.getarbol.com/api-reference/endpoints/connected-accounts/delete-a-composio-account https://api.getarbol.com/openapi.json delete /connected-accounts/{id} Deletes the account directly in Composio and removes its Arbol permissions. # Get a Composio account Source: https://docs.getarbol.com/api-reference/endpoints/connected-accounts/get-a-composio-account https://api.getarbol.com/openapi.json get /connected-accounts/{id} Returns one Composio-owned account and optionally counts current Arbol permissions that reference it. # List Composio accounts Source: https://docs.getarbol.com/api-reference/endpoints/connected-accounts/list-composio-accounts https://api.getarbol.com/openapi.json get /connected-accounts Lists the authenticated organization's connected accounts live from Composio. Arbol stores no account mirror. # Create a contact Source: https://docs.getarbol.com/api-reference/endpoints/contacts/create-a-contact https://api.getarbol.com/openapi.json post /contacts Creates one Contact and its supplied identities in the verified Organization under contacts:write. No idempotency key is accepted, so confirm an uncertain response before retrying. # Delete a contact Source: https://docs.getarbol.com/api-reference/endpoints/contacts/delete-a-contact https://api.getarbol.com/openapi.json delete /contacts/{id} Soft-deletes one tenant-owned Contact under contacts:write. A repeated request may return not found, so confirm an uncertain response before retrying. # Get a contact Source: https://docs.getarbol.com/api-reference/endpoints/contacts/get-a-contact https://api.getarbol.com/openapi.json get /contacts/{id} Returns one Contact together with a cursor page of its merged Conversation and Fact timeline under contacts:read and facts:read. Identity and current-Fact projections remain explicit expansions; timelineCursor and timelineLimit continue the embedded activity page without a second endpoint. The operation is side-effect free and retry-safe. # Import contacts Source: https://docs.getarbol.com/api-reference/endpoints/contacts/import-contacts https://api.getarbol.com/openapi.json post /contacts/import Accepts an HTTPS URL for one CSV file plus an exact header-to-field mapper under contacts:write. A Cloudflare Workflow downloads at most 2 MB and 500 rows, validates every mapped Contact, and imports them durably with tenant-local phone, email, and document identity deduplication. The response only confirms that background processing was queued. # List contacts Source: https://docs.getarbol.com/api-reference/endpoints/contacts/list-contacts https://api.getarbol.com/openapi.json get /contacts Lists Contact summaries in the verified Organization under contacts:read. The optional query searches names and identity addresses in the same cursor-paginated collection, replacing the former standalone search operation. It performs no writes and is safe to retry with the same cursor and filters. # Merge contacts Source: https://docs.getarbol.com/api-reference/endpoints/contacts/merge-contacts https://api.getarbol.com/openapi.json post /contacts/merge Atomically reattaches every tenant-owned reference to the primary Contact and retires the secondary under contacts:write. Repeating the completed merge may return not found; verify both Contacts before retrying. # Update a contact Source: https://docs.getarbol.com/api-reference/endpoints/contacts/update-a-contact https://api.getarbol.com/openapi.json patch /contacts/{id} Updates one tenant-owned Contact under contacts:write; supplied identity and address arrays replace their complete sets. There is no idempotency key, so inspect current state before replaying an uncertain request. # Delete a conversation Source: https://docs.getarbol.com/api-reference/endpoints/conversations/delete-a-conversation https://api.getarbol.com/openapi.json delete /conversations/{id} Soft-deletes one tenant-owned Conversation under conversations:write. A repeated request may return not found, so confirm an uncertain response before retrying. # Download conversation media Source: https://docs.getarbol.com/api-reference/endpoints/conversations/download-conversation-media https://api.getarbol.com/openapi.json post /conversations/{id}/download Under conversations:read and conversations:transcript, authorizes one persisted private Agents object and returns a short-lived read capability. API never fetches provider bytes; issuing another capability is side-effect free and retry-safe. # Get a conversation Source: https://docs.getarbol.com/api-reference/endpoints/conversations/get-a-conversation https://api.getarbol.com/openapi.json get /conversations/{id} Returns one Conversation under conversations:read and channels:read. Messages, Facts, and participants require their additional permissions; the operation is side-effect free and retry-safe. # List conversations Source: https://docs.getarbol.com/api-reference/endpoints/conversations/list-conversations https://api.getarbol.com/openapi.json get /conversations Lists Conversation summaries and Contact display projections in the verified Organization under conversations:read and contacts:read. It performs no writes and is safe to retry with the same cursor and filters. # Start an outbound conversation Source: https://docs.getarbol.com/api-reference/endpoints/conversations/start-an-outbound-conversation https://api.getarbol.com/openapi.json post /conversations Starts one outbound voice Conversation under conversations:write. Callers do not provide channelId: Agents validates the organization and Agent, prefers that Agent's active outbound voice channel, and otherwise uses the organization's enabled platform-managed global outbound line. Provider routing and persistence stay inside Agents. Reuse the same idempotencyKey after an uncertain response to recover the original Conversation instead of starting another call. # Update or close a conversation Source: https://docs.getarbol.com/api-reference/endpoints/conversations/update-or-close-a-conversation https://api.getarbol.com/openapi.json patch /conversations/{id} Updates or closes one tenant-owned Conversation under conversations:write; supplied Contact and Agent references are revalidated in the same tenant. Closing a non-test web or WhatsApp chat first persists its runtime transcript, then starts title, summary and assessment processing asynchronously. Repeating the close reuses the analysis instance. An in-flight reply returns conflict; retry after delivery. Metadata edits have no idempotency key, so read current state before replaying an uncertain request. # Create a definition Source: https://docs.getarbol.com/api-reference/endpoints/definitions/create-a-definition https://api.getarbol.com/openapi.json post /definitions Creates one typed Definition and its complete option set in the verified Organization under definitions:write. No idempotency key is accepted, so confirm an uncertain response before retrying. # Get a definition Source: https://docs.getarbol.com/api-reference/endpoints/definitions/get-a-definition https://api.getarbol.com/openapi.json get /definitions/{id} Returns one tenant-owned Definition under definitions:read with explicitly requested options or usage. It is side-effect free and safe to retry. # List definitions Source: https://docs.getarbol.com/api-reference/endpoints/definitions/list-definitions https://api.getarbol.com/openapi.json get /definitions Lists revisioned Definitions in the verified Organization under definitions:read. It performs no writes and is safe to retry with the same cursor and filters. # Update or retire a definition Source: https://docs.getarbol.com/api-reference/endpoints/definitions/update-or-retire-a-definition https://api.getarbol.com/openapi.json patch /definitions/{id} Updates one Definition under definitions:write using expectedRevision; supplied options replace the complete set and retirement is permanent. A successful request must not be blindly replayed because its revision is consumed. # Assert a fact Source: https://docs.getarbol.com/api-reference/endpoints/facts/assert-a-fact https://api.getarbol.com/openapi.json post /facts Appends an immutable assertion under facts:write; an unset value is an explicit tombstone and never deletes history. When supplied, the idempotencyKey and observedAt pair may be reused after an uncertain response to recover the same assertion. # List facts Source: https://docs.getarbol.com/api-reference/endpoints/facts/list-facts https://api.getarbol.com/openapi.json get /facts Lists current or historical immutable Fact assertions in the verified Organization under facts:read. It performs no writes and is safe to retry with the same cursor and subject. # Get an integration Source: https://docs.getarbol.com/api-reference/endpoints/integrations/get-an-integration https://api.getarbol.com/openapi.json get /integrations/{key} Returns one live-discovered integration under integrations:read without exposing provider identifiers or credentials. It performs no writes and is safe to retry. # List available integrations Source: https://docs.getarbol.com/api-reference/endpoints/integrations/list-available-integrations https://api.getarbol.com/openapi.json get /integrations Discovers provider-neutral business integrations live under integrations:read while excluding channel/runtime infrastructure. It stores nothing and is safe to retry subject to rate limits. # List integration tools Source: https://docs.getarbol.com/api-reference/endpoints/integrations/list-integration-tools https://api.getarbol.com/openapi.json get /integrations/{integrationKey}/tools Lists current provider-neutral tools live from Composio under integrations:read. It stores nothing and is safe to retry subject to rate limits. # Create a knowledge document upload Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/create-a-knowledge-document-upload https://api.getarbol.com/openapi.json post /knowledge Under knowledge:write, creates pending metadata and returns a five-minute direct R2 PUT capability. A document-scoped Workflow expires an unused capability or validates, promotes, and indexes uploaded bytes; callers observe progress with Get a knowledge document. No create idempotency key exists, so retain the returned document after an uncertain response. # Create a knowledge download capability Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/create-a-knowledge-download-capability https://api.getarbol.com/openapi.json post /knowledge/{id}/download Issues a short-lived direct read capability for completed source bytes under knowledge:read. It does not proxy the object or mutate document state, and requesting another capability is safe. # Delete a knowledge document Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/delete-a-knowledge-document https://api.getarbol.com/openapi.json delete /knowledge/{id} Soft-deletes one tenant-owned document under knowledge:write and schedules convergent object/index cleanup. Repeating the API request may return not found even while cleanup continues. # Get a knowledge document Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/get-a-knowledge-document https://api.getarbol.com/openapi.json get /knowledge/{id} Returns one tenant-owned Knowledge document projection under knowledge:read without reading its source bytes. It is side-effect free and safe to retry. # Get knowledge storage usage Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/get-knowledge-storage-usage https://api.getarbol.com/openapi.json get /knowledge/usage Returns tenant-scoped Knowledge document counts and durable source-byte usage under knowledge:read. It performs no storage scan or mutation and is safe to retry. # List knowledge documents Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/list-knowledge-documents https://api.getarbol.com/openapi.json get /knowledge Lists Knowledge document metadata and indexing state in the verified Organization under knowledge:read. It performs no ingestion work and is safe to retry with the same cursor and filters. # Reindex a knowledge document Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/reindex-a-knowledge-document https://api.getarbol.com/openapi.json post /knowledge/{id}/reindex Starts a document-scoped Workflow that upserts completed source bytes under knowledge:write and durably polls their index state. A later repeat starts another idempotent upsert. # Search knowledge documents Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/search-knowledge-documents https://api.getarbol.com/openapi.json post /knowledge/search Searches only the explicitly named ready documents under knowledge:read; text stays in the request body and never enters a URL. It stores no query or result state and is safe to retry subject to rate limits. # Update a knowledge document Source: https://docs.getarbol.com/api-reference/endpoints/knowledge/update-a-knowledge-document https://api.getarbol.com/openapi.json patch /knowledge/{id} Updates the display metadata or enabled state of one tenant-owned document under knowledge:write; source bytes are immutable. No idempotency key is accepted, so read current state before retrying an uncertain request. # Get the current organization Source: https://docs.getarbol.com/api-reference/endpoints/organization/get-the-current-organization https://api.getarbol.com/openapi.json get /organization Returns product settings for the verified user's active Auth0 Organization. Machine actors cannot call it; it performs no identity-provider or database writes and is safe to retry. # Cancel an outbound batch Source: https://docs.getarbol.com/api-reference/endpoints/outbound-batches/cancel-an-outbound-batch https://api.getarbol.com/openapi.json post /outbound-batches/{id}/cancel Stops dialing: pending recipients become cancelled, calls already in progress finish normally. Cancelling a finished batch returns 409. # Create an outbound batch Source: https://docs.getarbol.com/api-reference/endpoints/outbound-batches/create-an-outbound-batch https://api.getarbol.com/openapi.json post /outbound-batches Creates an outbound batch under conversations:write and starts dialing right away, at most five calls at a time per organization. Send up to 5000 recipients as JSON, or a csvUrl (https) to a CSV with a header row: phone_number (E.164) is required; name, first_message, prompt, and from_channel_id map to the recipient fields; any other column becomes a dynamic variable. The number each call leaves from is resolved per recipient: its fromChannelId, then the batch fromChannelId, then the Agent's own outbound channel, then the organization's platform-managed line. Batch-level firstMessage and prompt apply unless a recipient overrides them; {{variables}} are substituted by the voice provider. Calls start right away unless startAt is given; an optional schedule limits them to weekday windows in a time zone; at endAt whatever is still pending is cancelled as expired. Each accepted call becomes an ordinary outbound Conversation with originKind automation; a recipient settles only after that Conversation's post-call evaluation, and retries (retryOn) when nobody answered or the evaluation failed. Send idempotencyKey so a retried request returns the same batch instead of creating a second one. # Get an outbound batch Source: https://docs.getarbol.com/api-reference/endpoints/outbound-batches/get-an-outbound-batch https://api.getarbol.com/openapi.json get /outbound-batches/{id} Returns one outbound batch with its recipient counts by status. Poll it to follow progress; GET /outbound-batches/{id}/recipients lists the people and how each call went. # List outbound batch recipients Source: https://docs.getarbol.com/api-reference/endpoints/outbound-batches/list-outbound-batch-recipients https://api.getarbol.com/openapi.json get /outbound-batches/{id}/recipients Lists a batch's recipients in the order they were given, with status, attempts, next retry time, failure reason, the Conversation id once a call was placed, and that Conversation's success evaluation (outcome) once post-call analysis ran. Filter by status; GET /conversations/{id} has the transcript and summary. # List outbound batches Source: https://docs.getarbol.com/api-reference/endpoints/outbound-batches/list-outbound-batches https://api.getarbol.com/openapi.json get /outbound-batches Lists the organization's outbound batches, newest first, with recipient counts by status. Side-effect free. # List voices Source: https://docs.getarbol.com/api-reference/endpoints/voices/list-voices https://api.getarbol.com/openapi.json get /voices Returns bounded provider-neutral voice discovery to an authenticated Organization user under the baseline org:use grant. Provider identity and provider-only capabilities are not exposed; it stores nothing and is safe to retry subject to rate limits. # Preview a voice Source: https://docs.getarbol.com/api-reference/endpoints/voices/preview-a-voice https://api.getarbol.com/openapi.json post /voices/{voiceId}/preview Synthesizes one short voice-selection sample for an authenticated Organization user under the baseline org:use grant. Audio is generated on demand, not persisted, and has no idempotency requirement; retrying may incur another provider synthesis. # API reference overview Source: https://docs.getarbol.com/api-reference/overview How the Arbol REST reference is generated and how to use the production OpenAPI contract. The endpoint reference is generated directly from the live document at [`https://api.getarbol.com/openapi.json`](https://api.getarbol.com/openapi.json). The contract defines: * the production server URL and base path; * request path, query, and JSON body schemas; * success and error response schemas; * user and machine authentication alternatives; and * exact permissions for each operation. ## Source of truth Use the generated endpoint page for operation-specific limits and behavior. Handwritten guides explain cross-cutting patterns but do not replace the schema. The API repository generates OpenAPI from the same implemented router that serves REST requests. Only operations explicitly marked for publication enter this document. ## Request conventions * Send JSON request bodies with `Content-Type: application/json`. * Send bearer credentials in the `Authorization` header. * Use the production URL from the document's `servers` array. * Record the `X-Request-Id` response header for support and incident correlation. * Encode arrays and objects exactly as described by each query parameter's OpenAPI `style` and `explode` values. The interactive playground sends requests directly to the API rather than through a documentation proxy. Browser calls are therefore subject to the API's published CORS policy. ## Consolidated resource operations The public contract favors complete resource operations over technical substeps: * `listContacts` handles optional search across names, summary, and stable identities; * `getContact` includes a cursor-paginated conversation timeline; * `importContacts` queues a remote CSV import from a URL and field mapper; * `createConversation` selects and validates the organization's outbound voice capability when no Agent-owned channel exists; and * knowledge uploads advance through background reconciliation after the direct object upload. Internal callbacks, Workflow steps, storage completion helpers, and provider-only identifiers do not appear as public endpoints. ## Keeping generated pages current Because changing a remote OpenAPI document does not create a commit in this repository, the API deployment workflow must call Mintlify's Trigger deployment API after the new document is reachable in production. # Organizations and authority Source: https://docs.getarbol.com/concepts/organizations Understand how Arbol binds identities, permissions, and resources to one organization. An Arbol access token identifies both an actor and an organization. The API verifies those claims before it resolves any resource or executes a handler. ## Tenant boundary Organization identity comes from the verified credential. Public resource inputs therefore do not accept an `orgId` that changes the tenant boundary. This has three practical effects: 1. Resource identifiers are meaningful only inside the credential's organization. 2. A resource from another organization is never made accessible by supplying its identifier. 3. Organization membership and role changes take effect through the identity provider, not through a second API-owned permission store. ## Actors and permissions The OpenAPI contract can declare user-delegated and machine-to-machine security alternatives. Within either alternative, the listed scopes are an **all-of** requirement. For example, an operation that reads a conversation transcript can require both `conversations:read` and `conversations:transcript`. Possessing only one scope is insufficient. User tokens also carry the baseline organization grant declared by the contract. Machine credentials receive only the explicitly granted operation scopes. ## Design integrations around the boundary * Store Arbol resource identifiers with the organization context in your application. * Request the smallest permission set your integration needs. * Treat a `403` response as an authority decision, not as a signal to retry with a different organization identifier. * Re-authorize when membership, role, or connected-account access changes. # Contacts Source: https://docs.getarbol.com/guides/contacts Search, read, import, and merge organization contacts through the consolidated Contacts API. Contacts hold a person's names, summary, stable identities, facts, and conversation history inside one organization. The verified credential supplies the organization; requests never accept an `orgId` that can switch tenants. ## Search and browse Use `listContacts` for both browsing and free-text search. Pass `query` to match names, summary text, phone numbers, email addresses, or document identities. Matching is case- and accent-insensitive. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl --fail-with-body \ --get "${ARBOL_API_BASE}/contacts" \ --header "Authorization: Bearer ${ARBOL_ACCESS_TOKEN}" \ --data-urlencode "query=ana.munoz@example.com" \ --data-urlencode "limit=25" ``` Continue with `nextCursor` using the same query, sort, and filters. See [Pagination](/guides/pagination). ## Read a contact and its timeline `getContact` returns the contact, its identities and facts, and the first page of its conversation timeline. Set `timelineLimit` to control that embedded page and use `timelineCursor` to request the next one. This keeps the contact and its recent activity in one read. There is no separate public timeline operation. ## Import a remote CSV `importContacts` accepts two inputs: * `csvUrl`: a direct HTTPS URL to a CSV file; * `fieldMapper`: the exact CSV headers that map to Contact fields. At least one stable identity column—`phone`, `email`, or `document`—is required. Each source column can map to only one field. Keys inside `facts` are active Contact Definition identifiers; their values are CSV headers. ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "csvUrl": "https://files.example.com/contacts-2026-08.csv", "fieldMapper": { "givenName": "first_name", "familyName": "last_name", "phone": "phone_number", "email": "email", "summary": "notes", "facts": { "insurance-plan": "insurance_plan" } } } ``` The API returns `202 Accepted` with an `importId` and `status: "queued"`. A durable Workflow downloads and validates the file, then imports at most 500 rows and 2 MB. Existing contacts are matched within the organization by normalized phone, email, or document identity; ambiguous matches are not guessed. The source URL must return the CSV directly without redirects and remain available while the Workflow starts. Keep the `importId` for support and request correlation. ## Merge duplicates Use `mergeContacts` only after choosing one primary and one secondary Contact. The operation moves compatible identities and facts to the primary Contact, redirects owned relationships, and retires the secondary Contact. An identity conflict returns `409` instead of choosing an owner implicitly. # Errors Source: https://docs.getarbol.com/guides/errors Handle Arbol API errors, validation details, authorization failures, and request correlation. API errors are JSON data. Use the HTTP status and stable `code` to select a recovery path, then validate any `data` against that operation's generated error schema. Procedure errors can also include `status`, `defined`, and `inferable`. Do not depend on a JavaScript exception class, object identity or the wording of `message`. A client in Python, Go or another language uses the same documented fields. The [generated API reference](/api-reference/overview) is authoritative for the deployed response shapes; an internal SDK or service refactor does not create a second public error envelope. This validation example illustrates one documented response. Read the operation schema for the available issue fields and limits: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "defined": true, "inferable": true, "code": "BAD_REQUEST", "status": 400, "message": "Input validation failed", "data": { "issues": [ { "path": ["limit"], "message": "Too big: expected number to be <=100" } ], "truncated": false } } ``` ## Common status codes | Status | Meaning | Client action | | ------ | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | `400` | The request could not be decoded or did not match the input schema. | Correct the request. Do not retry unchanged. | | `401` | The bearer credential is missing, invalid, expired, or unusable for this environment. | Obtain a valid credential. | | `403` | The verified actor lacks one or more required permissions. | Request the missing authority or choose another operation. | | `404` | The resource does not exist in the verified organization or is not visible. | Confirm the identifier and tenant context. | | `409` | Current state conflicts with the requested mutation. | Read current state and reconcile revisions or idempotency keys. | | `413` | The transport body exceeds its byte limit. | Reduce the request body. | | `415` | The request media type is unsupported. | Use the media type declared by OpenAPI. | | `422` | The request is syntactically valid but violates a domain rule. | Correct the referenced resource or domain value. | | `429` | A rate limit was reached. | Wait for `data.retryAfterSeconds` when present. | | `500` | The service could not complete the request because of an unexpected failure. | Preserve the request reference and check state before replaying a mutation. | | `503` | A required downstream capability is temporarily unavailable. | Retry only when the operation is safe; use backoff. | ## Request references Responses produced by the API include `X-Request-Id`. Save that value with the operation ID, HTTP status and approximate UTC time when investigating a failure. An upstream gateway or network interruption may return a response without the API's error body or request reference; do not assume that an arbitrary HTML or empty response matches the schema. Request references help correlate an operation across service reports. They are not credentials, and they do not guarantee that every internal hop has a recorded distributed trace. When contacting support, share the reference and a description of the operation; omit access tokens, client secrets, patient data, signed URLs and raw provider responses. ## Unknown and transient failures Treat a malformed error body or an unrecognized code as an unknown failure. Preserve the reference and fall back to a safe user message; do not interpret exception text or allow an unknown error to imply success. A temporary failure does not prove that a mutation had no effect. Follow [retries and idempotency](/guides/retries-and-idempotency) before trying again. Reuse an operation's documented idempotency key with the same semantic input, or read current state when the operation has no replay guarantee. # Pagination Source: https://docs.getarbol.com/guides/pagination Traverse Arbol collections with opaque forward cursors without skipping or duplicating pages. Most list operations return a bounded page with this shape: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "items": [], "nextCursor": "opaque-cursor" } ``` ## Request the next page Pass the returned cursor back to the **same operation with the same filters and sort order**. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl --fail-with-body \ --get "${ARBOL_API_BASE}/agents" \ --header "Authorization: Bearer ${ARBOL_ACCESS_TOKEN}" \ --data-urlencode "limit=25" \ --data-urlencode "cursor=${NEXT_CURSOR}" ``` `nextCursor: null` means there is no next page. ## Rules * Treat cursors as opaque strings. Do not decode, modify, or construct them. * Do not reuse a cursor with different filters, sorting, or organization credentials. * Persist the cursor only when you need to resume a bounded traversal. * Restart from the first page when an operation rejects a stale or invalid cursor. The common list contract defaults to 25 items and permits at most 100. An endpoint can define a tighter bound, so use the value shown in its generated reference. # Retries and idempotency Source: https://docs.getarbol.com/guides/retries-and-idempotency Retry Arbol API operations without duplicating calls, facts, contacts, or provider mutations. Retry behavior is operation-specific. Read the operation description before replaying a mutation after a timeout or lost response. ## Safe retry policy 1. Retry side-effect-free reads with bounded exponential backoff and jitter. 2. For `429`, honor a returned `Retry-After` header and any documented `data.retryAfterSeconds`. A retry delay is a minimum wait, not permission to repeat an unsafe mutation. 3. Retry `503` only when the operation description says it is safe or the request has a stable idempotency key. 4. Do not retry other `4xx` responses unchanged. 5. Cap retries and surface the final `X-Request-Id` for support. ## Mutations Some operations accept a domain `idempotencyKey`. Reuse the **same key with the same semantic input** after an uncertain response. Examples in the generated contract include starting an outbound conversation and, when supplied with a stable observation timestamp, asserting a fact. If an operation has no idempotency key, read current state before replaying it. This applies to many creates, provider onboarding actions, and complete-set updates. A new idempotency key creates a new logical attempt. Generating a fresh key for every retry defeats idempotency. ## Optimistic revisions Operations that accept `expectedRevision` use it to prevent lost updates. On `409`, use the returned current revision when available, fetch the resource again, and apply your change to the new state. Do not loop by replacing the revision without reconciling the data. ## Network and service boundaries A timeout, disconnected client or `5xx` response can arrive after a downstream operation has already committed. Retrying from a different process or through MCP does not create a new idempotency guarantee. The owning API operation determines whether the same key and input can be replayed. For a safe retry, keep a bounded attempt count and total deadline, add jitter to exponential backoff, and stop when the operation returns a permanent validation or authorization refusal. Keep the request reference from each attempt so support can distinguish the original uncertain outcome from later retries. Never log credentials or mutation payloads as retry diagnostics. # Uploads and downloads Source: https://docs.getarbol.com/guides/uploads-and-downloads Move private object bytes through short-lived capabilities while keeping API authority tenant-scoped. The API authorizes object access but does not proxy private file bytes. It returns short-lived, object-scoped URLs for direct transfer. ## Upload a knowledge document Call `createKnowledgeDocument` with the file name, byte size, media type, and display name. The response contains the pending document and an `upload` capability. Send the file to `upload.url` with the returned HTTP method and every header in `upload.headers`. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl --fail-with-body \ --request PUT \ --header "Content-Type: application/pdf" \ --upload-file "operations-manual.pdf" \ "${UPLOAD_URL}" ``` Do not send your Arbol bearer token to the object URL. Use only the headers returned with the capability. Arbol detects the uploaded object, validates its size and media type, promotes it from pending storage, and indexes it in the background. Poll `getKnowledgeDocument` with bounded backoff until its index state is ready or reports an error. The generated endpoint schema is authoritative for file-size and media-type limits. There is no public “complete upload” endpoint. Completion is internal plumbing: the reconciliation loop makes an uploaded object durable even when the client disconnects after the direct PUT. ## Download private content Conversation media, knowledge source bytes, and retained evaluation artifacts use authorization operations that return a short-lived read URL. Fetch that URL without forwarding the Arbol bearer token. Creating another download capability is safe, but each URL expires. Do not persist it as the durable identifier for an object. ## Security rules * Keep the returned capability URL out of logs and analytics. * Never change the method, signed headers, or object key embedded in a capability. * Use the API resource ID as the durable reference. * Re-authorize immediately before a transfer rather than caching capabilities. # Arbol developer documentation Source: https://docs.getarbol.com/introduction Use the Arbol API and MCP to work with organization-scoped agents, conversations, contacts, knowledge, and integrations. Arbol exposes an organization-scoped REST API for operating conversational agents and a planned Model Context Protocol (MCP) surface for OAuth-capable AI clients. The [public OpenAPI document](https://api.getarbol.com/openapi.json) is the contract for the production REST API. Endpoint pages in this site are generated from that document, including request schemas, response schemas, required permissions, and examples. Make an authenticated request against the server declared by the live OpenAPI contract. Browse the generated REST reference and permission requirements. Learn how the standalone MCP wrapper is derived from the public API. ## Contract boundaries * Every authenticated request is bound to one verified organization. A request body or query string cannot select another organization. * The endpoint's OpenAPI `security` declaration lists every permission required for that operation. * List responses use opaque forward cursors. See [Pagination](/guides/pagination). * Private object bytes move through short-lived, object-scoped capabilities rather than through the API Worker. See [Uploads and downloads](/guides/uploads-and-downloads). The standalone MCP endpoint, delegated OAuth exchange, and Composio toolkit must all pass their deployment checklist before production use. The MCP pages describe the intended integration and its activation prerequisites; they do not claim that the rollout is complete. # Connect MCP through Composio Source: https://docs.getarbol.com/mcp/composio Prerequisites and verification steps for publishing the Arbol MCP server as a Composio Custom MCP toolkit. Composio connects to Arbol as a Custom MCP toolkit using dynamic-client-registration OAuth. Registration and synchronization are deployment operations owned by the standalone MCP repository. ## Prerequisites Complete these before registering the toolkit: 1. Deploy `https://mcp.getarbol.com/mcp` and verify its health and MCP protocol behavior. 2. Publish MCP protected-resource metadata and Auth0 authorization-server metadata over HTTPS. 3. Enable dynamic client registration for approved third-party clients. 4. Enable on-behalf-of exchange from the MCP resource server to the Arbol API audience. 5. Confirm that the deployed API OpenAPI contract is the version used to generate MCP tools. Registering a toolkit before OAuth and the MCP endpoint are reachable creates an unusable integration. A successful toolkit upsert does not prove that authentication or tool execution works. ## Registration model The toolkit uses Composio's `DCR_OAUTH` mode and the authorization server's discovery URL. Its immutable application URL and OAuth resource are the exact MCP endpoint, `https://mcp.getarbol.com/mcp`, not the origin URL. The repository's registration script owns the exact API payload, toolkit slug, and icon. After one approved connected account exists, synchronize the toolkit so Composio reads the current MCP tool list. Re-run synchronization after a deployed OpenAPI change modifies generated tools. ## Verify the integration Connect one test user from an Arbol organization and confirm consent is granted to the exact MCP resource. Use non-production data for the smoke test. Compare Composio's tool inventory with the generated manifest from the same OpenAPI revision. Unexpected meta-tools or missing operations fail the rollout. Execute a bounded read such as listing agents and verify that results come from the test user's organization. Verify expired tokens, missing API scopes, cross-organization identifiers, and revoked connections fail closed. Do not publish mutation tools to production until read-only execution, delegated authority, audit correlation, and revocation have all passed. For the current Custom MCP requirements, see [Composio's Custom MCP documentation](https://docs.composio.dev/docs/extending-sessions/custom-mcp). # MCP failures and recovery Source: https://docs.getarbol.com/mcp/errors Distinguish MCP authentication, protocol and tool failures, and recover without replaying an unsafe API mutation. MCP clients must distinguish admission to the server, validity of the MCP request and the outcome of a tool call. A successful HTTP exchange does not by itself mean a tool completed successfully. The Arbol MCP integration still has the [rollout prerequisites](/mcp/overview#rollout-status) described in its overview. This guide explains the protocol and client recovery model; it does not confirm production activation. ## Three failure boundaries | Boundary | What the client observes | Recovery | | ------------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | Authentication or authorization to the MCP server | An HTTP challenge or refusal before a tool executes. | Obtain a valid token for the MCP audience and the required admission scope. | | MCP protocol | A JSON-RPC error for an invalid request or unsupported protocol operation. | Correct the request or client/server negotiation. | | Tool execution | A tool result with `isError: true`. | Inspect the safe result content and follow that operation's recovery rules. | MCP defines tool execution failures separately from JSON-RPC protocol errors so a caller can understand and act on the tool outcome. Check `isError` before treating content as success. When a tool declares structured output, validate it against the advertised output schema; text is not a substitute for that contract. See the [MCP tool specification](https://modelcontextprotocol.io/specification/2025-11-25/server/tools#error-handling). ## Downstream API refusals Arbol MCP calls the public API using delegated authority. An API validation failure, revision conflict or missing permission does not become permission to try another organization, account or credential. The API remains the authority for its resource and operation. Its [generated contract](/api-reference/overview) defines the available input, output and error data. Do not parse an internal exception name or English message to infer a business outcome. Retain a request reference when a response provides one and report it with the tool name and approximate time. Do not share bearer tokens, patient data, tool arguments or raw upstream responses as troubleshooting material. ## Retry only with the operation's guarantee A tool call can fail after an API mutation has committed. A fresh MCP request id does not make replay safe and is not a domain idempotency key. Reuse only the idempotency key declared by the underlying operation, with the same semantic input; otherwise inspect current state before repeating the tool call. For an authorization failure, correct the delegated credentials or permissions. For a validation failure, correct the input. For a revision conflict, read and reconcile the resource. Temporary dependency failures may be retried with bounded backoff only when the operation is safe to repeat. See [retries and idempotency](/guides/retries-and-idempotency). # MCP OAuth Source: https://docs.getarbol.com/mcp/oauth The two-audience OAuth and on-behalf-of flow for an Arbol user calling API-backed MCP tools. The MCP server and the Arbol API are separate OAuth resources. A token issued for one audience must not be accepted by the other. The MCP OAuth resource identifier and token audience are exactly: ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} https://mcp.getarbol.com/mcp ``` OAuth clients must send that same value in the `resource` parameter. `https://mcp.getarbol.com/` identifies a different resource and is not interchangeable with the MCP endpoint. ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} AI client | MCP audience token v Arbol MCP | on-behalf-of exchange | API audience token v Arbol API ``` ## Request flow 1. The client discovers the MCP protected resource and authorization server. 2. Dynamic client registration creates an approved OAuth client. 3. A person authorizes the MCP client in the context of their organization. 4. The client sends the resulting MCP-audience bearer token to the MCP endpoint. 5. MCP verifies issuer, audience, signature, expiry, organization context, and the MCP access scope. 6. MCP exchanges that verified token for an API-audience token on the person's behalf. 7. MCP calls the generated REST operation with the exchanged token. 8. The API independently verifies organization and operation permissions. Every Arbol organization can authorize MCP. The connection grants no additional API authority: each call remains limited to the person's verified organization membership, roles, scopes, and the permissions declared for that operation. ## Required metadata The deployment must expose and verify: * MCP protected-resource metadata under `https://mcp.getarbol.com/.well-known/oauth-protected-resource`; * authorization-server metadata from the configured Auth0 custom domain; * a dynamic-client-registration endpoint; and * the downstream API protected-resource metadata at `https://api.getarbol.com/.well-known/oauth-protected-resource`. ## Security invariants * MCP never forwards the incoming MCP token directly to the API. * The incoming token's audience must equal `https://mcp.getarbol.com/mcp`. * The exchanged token's audience is the API, and its scopes are bounded by the delegated user authority. * Organization identity comes from verified token claims, never tool arguments. * Tool execution still receives `401` or `403` from the API when delegated authority is invalid or insufficient. * Token exchange credentials remain server-side and are never returned through MCP content. This flow is a deployment prerequisite, not a statement that dynamic registration and token exchange are already enabled in production. See Auth0's [MCP on-behalf-of guide](https://auth0.com/ai/docs/mcp/get-started/call-your-apis-on-users-behalf) and [on-behalf-of token exchange documentation](https://auth0.com/docs/secure/call-apis-on-users-behalf/on-behalf-of-token-exchange) for the identity-provider requirements. # Arbol MCP overview Source: https://docs.getarbol.com/mcp/overview How the standalone Arbol MCP server turns the published OpenAPI contract into organization-scoped tools. The standalone Arbol MCP server is designed as a stateless wrapper around the public REST API. ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} AI client -> Arbol MCP -> Arbol public API ``` It does not read Arbol's database, mirror organization state, or own a second permission model. The API remains the authorization and business-logic boundary. ## Generated tools At build time, the MCP repository reads the public OpenAPI contract and generates tools from published operations. The generated definition preserves: * the OpenAPI `operationId` and description; * path, query, and JSON body schemas; * the production server and HTTP method; * required API permissions; and * read-only, idempotent, or destructive hints where the contract supports them. A small number of model-oriented tools can optimize common workflows by composing published API operations. Those tools still call the API and do not receive direct database access. ## Delegated authority The MCP endpoint verifies a token issued for the exact `https://mcp.getarbol.com/mcp` audience. It then uses OAuth on-behalf-of exchange to obtain a short-lived API token for the downstream API audience. See [MCP OAuth](/mcp/oauth). MCP is available to every Arbol organization. Connecting it does not add an organization role or grant API permissions. The API authorizes each tool call from the user's verified organization membership, roles, scopes, and the operation's OpenAPI security requirements. ## Rollout status Treat the MCP integration as unavailable until Arbol confirms all of the following: the standalone Worker is deployed, OAuth discovery and dynamic client registration are live, on-behalf-of exchange is enabled, the Composio toolkit is synchronized, and an end-to-end tool call succeeds. The intended Streamable HTTP endpoint is: ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} https://mcp.getarbol.com/mcp ``` Do not configure a production client against that URL until the rollout status is confirmed. # Quickstart Source: https://docs.getarbol.com/quickstart Discover the production API base URL and make your first authenticated Arbol request. ## Prerequisites You need: * an approved Arbol organization; * a bearer credential issued through your organization's onboarding flow; and * the permissions required by the operation you call. Registration and credentials are provisioned during onboarding. Do not put access tokens in source control, URLs, or logs. ## Make a request Export the credential in your shell without writing it to a file. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} export ARBOL_ACCESS_TOKEN="your-access-token" ``` The contract owns the base path, so derive it instead of hard-coding a path that can drift. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} export ARBOL_API_BASE="$( curl --fail --silent https://api.getarbol.com/openapi.json \ | jq --raw-output '.servers[0].url' )" ``` Your credential must satisfy the security requirements shown for `listAgents` in the generated reference. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl --fail-with-body \ --header "Authorization: Bearer ${ARBOL_ACCESS_TOKEN}" \ --header "Accept: application/json" \ "${ARBOL_API_BASE}/agents?limit=10" ``` A successful paginated response contains `items` and `nextCursor`. When `nextCursor` is `null`, the collection has no next page. ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "items": [], "nextCursor": null } ``` Next, read [Authentication](/api-reference/authentication) and [Errors](/guides/errors) before adding mutation requests.