Endpoints
Every /v1 route, grouped by resource, with a curl example for each.
Every route needs Authorization: Bearer $DEXBY_API_KEY. Successful REST responses usually wrap
the result in { "data": ... }; MCP responses use JSON-RPC. The API key decides the project.
Base URL, errors, and paging are in the REST API overview.
Connectors
GET /v1/connectors
One page of the connectors the project can use: built-in connectors (most popular first, then by id) plus the project's own MCP servers and imported REST APIs.
| Query | Type | Default | What it does |
|---|---|---|---|
query | string | none | Search text in id, name, and description. 1 to 200 characters. |
category | string | none | communication, developer-tools, crm, productivity, marketing, analytics, finance, storage, security, or commerce. |
popular | boolean | none | true: only the most popular, in rank order. |
facets | boolean | false | Adds facets: { category, popular } counts. |
limit | integer | 100 | 1 to 500. |
cursor | string | none | The previous page's nextCursor. |
curl "https://api.dexby.ai/v1/connectors?query=chat&limit=1" \
-H "Authorization: Bearer $DEXBY_API_KEY"{
"data": [
{
"id": "slack",
"name": "Slack",
"description": "Channels, messages, and users.",
"category": "communication",
"logo": "https://assets.dexby.ai/logos/slack",
"authMethods": [{ "id": "oauth2", "type": "oauth2", "name": "OAuth" }],
"mcp": false
}
],
"nextCursor": "00001slack"
}GET /v1/connectors/:id
One connector with its authMethods and toolIds. toolIds is absent for MCP servers, whose
tools come from the server. An unknown id answers 404 CONNECTOR_NOT_FOUND.
| Path | Where to get it |
|---|---|
:id | Connector id, such as slack. From GET /v1/connectors, Build → Catalog in the dashboard, or the connectors page. |
curl "https://api.dexby.ai/v1/connectors/slack" \
-H "Authorization: Bearer $DEXBY_API_KEY"{
"data": {
"id": "slack",
"name": "Slack",
"category": "communication",
"authMethods": [{ "id": "oauth2", "type": "oauth2", "name": "OAuth" }],
"toolIds": ["slack_list_conversations", "slack_post_message"]
}
}Tools
GET /v1/tools
One page of the project's tools, sorted by id. Tools turned off in the project are left out.
| Query | Type | Default | What it does |
|---|---|---|---|
query | string | none | Search text, 1 to 200 characters. |
connectorId | string | none | Only this connector's tools. |
category | string | none | Same values as for connectors. |
dataClassification | string | none | standard, pii, or phi. |
view | string | full | index leaves out requiredScopes, inputSchema, and outputSchema. |
facets | boolean | false | Adds counts per category and dataClassification. |
limit, cursor | See pagination. |
curl "https://api.dexby.ai/v1/tools?connectorId=slack&view=index" \
-H "Authorization: Bearer $DEXBY_API_KEY"{
"data": [
{
"id": "slack_post_message",
"name": "Post message",
"description": "Post a message to a channel.",
"connectorId": "slack",
"effect": "write",
"category": "communication",
"dataClassification": "pii"
}
],
"nextCursor": null
}effect is read, write, or destructive.
POST /v1/tools/execute
Runs one tool for one user with their stored credential, outside any session.
| Body | Type | Default | What it is |
|---|---|---|---|
toolId | string | required | Tool id, such as slack_post_message. From GET /v1/tools or Build → Catalog. |
input | object | {} | Must match the tool's inputSchema. |
userId | string | "default" | Your own id for the end user. default is the project-level user. |
connectionId | uuid | none | One of the user's accounts. From GET /v1/connections?userId=user_123. Otherwise the default account. |
allowGlobalAccounts | boolean | false | Lets the call choose one of the project's global accounts. Without it, a global account is used only when connectionId names it. |
curl "https://api.dexby.ai/v1/tools/execute" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"toolId":"slack_post_message","userId":"user_123","input":{"channel":"general","text":"Deploy finished"}}'{ "data": { "ok": true, "channel": "C0123", "ts": "1727500000.000100" } }data is the tool's result. Failures answer an HTTP error such as 400 MISSING_CONNECTION. A
global account runs only the tools an admin allowed it; any other answers 403 ACTION_DISABLED.
POST /v1/tools/proxy
Sends a raw request to a connector's API with the user's credential, for endpoints no tool covers. The path stays on the connector's API host.
| Body | Type | Default | What it is |
|---|---|---|---|
connectorId | string | required | Connector id. |
userId | string | required | Your own id for the end user. |
endpoint | string | required | Path relative to the connector's API base URL. |
method | GET, POST, PUT, PATCH, DELETE | GET | HTTP method. |
query | object | none | Query parameters. |
body | any JSON | none | Request body. |
headers | Record<string, string> | none | Extra headers. authorization, proxy-authorization, cookie, and host are dropped. |
connectionId | uuid | none | One of the user's accounts, as for execute. |
allowGlobalAccounts | boolean | false | As for execute. A global account also needs its Allow proxy permission, else 403 ACTION_DISABLED. |
curl "https://api.dexby.ai/v1/tools/proxy" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"connectorId":"github","userId":"user_123","endpoint":"/user"}'{ "data": { "login": "octocat", "id": 1 } }data is the provider's response body. A connector without a proxy base URL, or a path that
leaves its host, answers 403 FORBIDDEN_ENDPOINT. A provider error answers 502 UPSTREAM_ERROR.
Sessions
POST /v1/sessions
Creates a session for one user. Answers 201.
| Body | Type | Default | What it is |
|---|---|---|---|
userId | string | required | Your own id for the end user, up to 256 characters. |
connectors | string[] | all | Only these connector ids. 1 to 200. |
actions | string[] | all | Only these tool ids, or prefixes ending in * (such as slack_*). 1 to 500. |
pinned | string[] | [] | Tool ids listed as full definitions next to the meta tools. At most 20, all in scope. |
accounts | Record<string, string> | {} | Connector id to account id, name, or label, for when a call names no account. |
allowGlobalAccounts | boolean | false | Lets the agent see and use the project's global accounts. Off, they do not exist for the session. |
policy.readOnly | boolean | false | Only read tools. |
policy.maxDataClass | standard, pii, phi | phi | Most sensitive data class allowed. |
policy.allowDisconnect | boolean | false | Adds dexby_disconnect_account. |
policy.allowProxy | boolean | false | Adds dexby_proxy. |
ttlMinutes | integer | 1440 | Lifetime, 5 to 43200 minutes. |
curl "https://api.dexby.ai/v1/sessions" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"userId":"user_123","connectors":["slack"],"pinned":["slack_post_message"]}'{
"data": {
"id": "0192f3c1-7a2b-7c3d-9e4f-5a6b7c8d9e0f",
"userId": "user_123",
"expiresAt": "2026-09-29T10:00:00.000Z",
"scopeHash": "c3a1f0",
"actionCount": 12,
"pinned": ["slack_post_message"],
"policy": {
"readOnly": false,
"maxDataClass": "phi",
"allowDisconnect": false,
"allowProxy": false
},
"allowGlobalAccounts": false,
"connectors": [
{ "id": "slack", "name": "Slack", "actions": 12, "connection": { "status": "missing" } }
],
"mcpUrl": "https://api.dexby.ai/v1/sessions/0192f3c1-7a2b-7c3d-9e4f-5a6b7c8d9e0f/mcp"
}
}connection.status is connected, missing, or reauth_required. accounts is added when the
user has more than one account for the connector. scopeHash changes when the scope changes.
GET /v1/sessions/:id
The session with current connection states. Same shape as create. An unknown or expired session
answers 404 SESSION_NOT_FOUND.
| Path | Where to get it |
|---|---|
:id | Session id: data.id from POST /v1/sessions, or Operate → Sessions in the dashboard. |
curl "https://api.dexby.ai/v1/sessions/<session-id>" \
-H "Authorization: Bearer $DEXBY_API_KEY"GET /v1/sessions/:id/tools
Tool definitions for the model: the meta tools, then the pinned tools.
| Param | Where | What it is |
|---|---|---|
:id | path | Session id, as above. |
format | query, default json-schema | json-schema, or openai-strict for OpenAI strict mode. |
curl "https://api.dexby.ai/v1/sessions/<session-id>/tools?format=openai-strict" \
-H "Authorization: Bearer $DEXBY_API_KEY"{
"data": {
"scopeHash": "c3a1f0",
"tools": [
{
"kind": "meta",
"name": "dexby_search_actions",
"description": "Find actions you can run for this user. ...",
"inputSchema": { "type": "object", "properties": { "queries": { "type": "array" } } },
"annotations": { "readOnlyHint": true, "destructiveHint": false },
"strict": true
}
]
}
}kind is meta or action (a pinned tool). The meta tools are described in
sessions.
POST /v1/sessions/:id/tools/:name
Runs one session tool with the model's arguments. Answers 200 with { ok: true, result }, or a
refusal { ok: false, error: { code, message } } for the model to act on
(see errors). An unknown tool answers 404 TOOL_NOT_FOUND.
| Param | Where | What it is |
|---|---|---|
:id | path | Session id, as above. |
:name | path | Tool name from GET /v1/sessions/:id/tools, such as dexby_execute. |
arguments | body | The model's arguments for the tool. |
curl "https://api.dexby.ai/v1/sessions/<session-id>/tools/dexby_execute" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"arguments":{"action":"slack_post_message","input":{"channel":"general","text":"Deploy finished"}}}'If Slack is not connected for the session's user, execution returns this refusal:
{
"data": {
"ok": false,
"error": {
"code": "connection_required",
"message": "Slack is not connected for this user. ...",
"connector": "slack"
}
}
}POST /v1/sessions/:id/mcp
The session as an MCP server over Streamable HTTP (JSON responses), with the same tools and scope.
GET and DELETE answer 405 with Allow: POST. An unknown session answers a JSON-RPC error
with status 404.
| Path | Where to get it |
|---|---|
:id | Session id. The full URL is data.mcpUrl from POST /v1/sessions. |
curl "https://api.dexby.ai/v1/sessions/<session-id>/mcp" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Client configs are in MCP.
Connections
GET /v1/connections
The user's accounts, oldest first: their own and the project's
global accounts, which carry "global": true. Listing
shows global accounts whether or not a call may use them. userId is required.
| Query | What it is |
|---|---|
userId | Your own id for the end user. |
curl "https://api.dexby.ai/v1/connections?userId=user_123" \
-H "Authorization: Bearer $DEXBY_API_KEY"{
"data": [
{
"id": "0190d6a4-5b7e-7c3a-9f10-2b3c4d5e6f70",
"connectorId": "slack",
"authConfigId": "0190d6a4-0000-7000-8000-000000000001",
"name": "default",
"label": "Acme workspace",
"isDefault": true,
"status": "active",
"scopes": ["chat:write"],
"lastUsedAt": null,
"createdAt": "2026-09-28T10:00:00.000Z",
"global": false
}
]
}POST /v1/connections
Stores a credential you already hold as a new account. Answers 200. A name the user already
has for this connector answers 409 CONFLICT.
| Body | Type | Default | What it is |
|---|---|---|---|
connectorId | string | required | Connector id. |
userId | string | required | Your own id for the end user. Omit it with global. |
global | boolean | false | true connects a global account, which every user of the project may use. Give either userId or global. |
credential | object | required | type is oauth2, oauth2_client_credentials, api_key, basic, aws_iam, custom, or none. Unknown fields are rejected. |
authConfig | string | the first | Auth config key, from the "Key" field in Build → Auth configs. |
name | string | next free name | Account name, up to 64 characters. The user's first account for a connector is default. |
curl "https://api.dexby.ai/v1/connections" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"connectorId":"linear","userId":"user_123","credential":{"type":"api_key","apiKey":"<linear-api-key>"}}'<linear-api-key> is the user's own key from the provider.
{
"data": {
"id": "0190d6a4-5b7e-7c3a-9f10-2b3c4d5e6f70",
"connectorId": "linear",
"userId": "user_123",
"global": false,
"name": "default",
"label": null,
"isDefault": true,
"status": "active"
}
}A global account answers with "userId": null and "global": true, and is never a default. It
may run no action until an admin allows some in the dashboard.
PATCH /v1/connections/:id
Renames an account with { name }, or rotates its credential with
{ credential, expectedRevision }.
| Param | Where | What it is |
|---|---|---|
:id | path | Connection id (uuid): id from GET /v1/connections?userId=user_123, or Operate → Connections → "Connection ID". |
name | body | New account name. A name the user already has answers 409 NAME_TAKEN. |
credential | body | The new credential, same shape as on create. |
expectedRevision | body | The revision you are replacing. A stale revision answers 409 CONFLICT. |
curl -X PATCH "https://api.dexby.ai/v1/connections/<connection-id>" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"work"}'{ "data": { "id": "0190d6a4-5b7e-7c3a-9f10-2b3c4d5e6f70", "name": "work" } }A rotation answers { id, revision } and sets a reauth_required connection back to active.
POST /v1/connections/:id/default
Makes the account the user's default for its connector. A global account answers
400 VALIDATION_ERROR: it is shared, so it is no one's default.
| Path | Where to get it |
|---|---|
:id | Connection id, as for PATCH. |
curl -X POST "https://api.dexby.ai/v1/connections/<connection-id>/default" \
-H "Authorization: Bearer $DEXBY_API_KEY"{
"data": {
"id": "0190d6a4-5b7e-7c3a-9f10-2b3c4d5e6f70",
"connectorId": "slack",
"isDefault": true
}
}DELETE /v1/connections/:id
Removes the account, its credential, and its triggers. When it was the default, the user's next account becomes the default.
| Path | Where to get it |
|---|---|
:id | Connection id, as for PATCH. |
curl -X DELETE "https://api.dexby.ai/v1/connections/<connection-id>" \
-H "Authorization: Bearer $DEXBY_API_KEY"{ "data": { "id": "0190d6a4-5b7e-7c3a-9f10-2b3c4d5e6f70", "erased": true } }Connect links
POST /v1/connect-links
Creates a single-use link to the hosted Connect page, where the user connects their own accounts.
Answers 201. Send url to the user.
| Body | Type | Default | What it is |
|---|---|---|---|
userId | string | required | Your own id for the end user, up to 256 characters. |
connectors | string[] | all | Offer every auth config of these connector ids. |
authConfigs | string[] | all | Offer these auth configs, by key from Build → Auth configs. |
redirectUrl | string | none | Where the user goes afterward. Must be allowed in Configure → Connect UI, or 400. |
expiresInMinutes | integer | 30 | 5 to 1440. |
curl "https://api.dexby.ai/v1/connect-links" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"userId":"user_123","connectors":["slack"]}'{
"data": {
"id": "0192f3c1-0000-7000-8000-00000000abcd",
"url": "https://dexby.ai/connect/<token>",
"userId": "user_123",
"authConfigs": ["slack"],
"expiresAt": "2026-09-28T10:30:00.000Z"
}
}authConfigs is null when the link offers every auth config. See
connect accounts.
Triggers
GET /v1/triggers
The project's triggers.
curl "https://api.dexby.ai/v1/triggers" \
-H "Authorization: Bearer $DEXBY_API_KEY"{
"data": [
{
"id": "0192f3c1-1111-7000-8000-000000000001",
"connectionId": "0190d6a4-5b7e-7c3a-9f10-2b3c4d5e6f70",
"connectorId": "slack",
"event": "app_mention",
"userId": "user_123",
"fireCount": 3,
"lastFiredAt": "2026-09-28T09:12:00.000Z",
"createdAt": "2026-09-27T10:00:00.000Z"
}
]
}POST /v1/triggers
Subscribes to one event on one connection. Answers 201. Events reach your webhooks as
trigger.fired.
| Body | Type | What it is |
|---|---|---|
connectionId | uuid | Required. From GET /v1/connections?userId=user_123, or Operate → Connections → "Connection ID". |
event | string | Required. Trigger event id, such as app_mention. From GET /api/catalog/:connectorId → triggers[].id, or the connector page in Build → Catalog. |
secret | string | Manual setup only (such as Slack): the provider's signing secret, up to 512 characters. |
curl "https://api.dexby.ai/v1/triggers" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"connectionId":"<connection-id>","event":"app_mention","secret":"<slack-signing-secret>"}'<slack-signing-secret> is in your Slack app's Basic Information page.
{
"data": {
"id": "0192f3c1-1111-7000-8000-000000000001",
"connectorId": "slack",
"event": "app_mention",
"fireCount": 0,
"url": "https://api.dexby.ai/api/triggers/<token>"
}
}url appears only for manual setup, only on create. Paste it into the provider's settings. See
triggers.
DELETE /v1/triggers/:id
Removes a trigger.
| Path | Where to get it |
|---|---|
:id | Trigger id: id from GET /v1/triggers or create. |
curl -X DELETE "https://api.dexby.ai/v1/triggers/<trigger-id>" \
-H "Authorization: Bearer $DEXBY_API_KEY"{ "data": { "id": "0192f3c1-1111-7000-8000-000000000001" } }MCP
POST https://mcp.dexby.ai/:slug/:userId
Serves one of the project's MCP endpoints over Streamable HTTP (JSON responses). Each call uses
the connected accounts of the user in the path. When the user has not connected the app, the tool result carries a connect
link. GET and DELETE answer 405 with Allow: POST. An unknown slug answers a JSON-RPC error
with status 404, and any other path on the MCP host answers 404. Both MCP routes answer 403 to
browser requests whose Origin is not Dexby's web app.
| Param | Where | What it is |
|---|---|---|
:slug | path | Endpoint slug you chose in Distribute → MCP endpoints → New endpoint ("URL slug"). No /v1 route lists endpoints. |
:userId | path | Your own id for the end user, percent-encoded as one segment. Without it, calls use default, or are refused when the endpoint requires a user. |
curl "https://mcp.dexby.ai/<endpoint-slug>/user_123" \
-H "Authorization: Bearer $DEXBY_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'The API host also serves the endpoint at POST /v1/mcp/:slug/:userId.
Self-hosted deployment packaging is planned.
Legacy: POST /v1/mcp/:slug?user=<userId> still works and behaves the same.
The endpoint page in the dashboard shows the full URL and ready configs for Claude Code and Cursor. See MCP.