Dexby

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.

QueryTypeDefaultWhat it does
querystringnoneSearch text in id, name, and description. 1 to 200 characters.
categorystringnonecommunication, developer-tools, crm, productivity, marketing, analytics, finance, storage, security, or commerce.
popularbooleannonetrue: only the most popular, in rank order.
facetsbooleanfalseAdds facets: { category, popular } counts.
limitinteger1001 to 500.
cursorstringnoneThe previous page's nextCursor.
terminal
curl "https://api.dexby.ai/v1/connectors?query=chat&limit=1" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{
	"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.

PathWhere to get it
:idConnector id, such as slack. From GET /v1/connectors, Build → Catalog in the dashboard, or the connectors page.
terminal
curl "https://api.dexby.ai/v1/connectors/slack" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{
	"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.

QueryTypeDefaultWhat it does
querystringnoneSearch text, 1 to 200 characters.
connectorIdstringnoneOnly this connector's tools.
categorystringnoneSame values as for connectors.
dataClassificationstringnonestandard, pii, or phi.
viewstringfullindex leaves out requiredScopes, inputSchema, and outputSchema.
facetsbooleanfalseAdds counts per category and dataClassification.
limit, cursorSee pagination.
terminal
curl "https://api.dexby.ai/v1/tools?connectorId=slack&view=index" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{
	"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.

BodyTypeDefaultWhat it is
toolIdstringrequiredTool id, such as slack_post_message. From GET /v1/tools or Build → Catalog.
inputobject{}Must match the tool's inputSchema.
userIdstring"default"Your own id for the end user. default is the project-level user.
connectionIduuidnoneOne of the user's accounts. From GET /v1/connections?userId=user_123. Otherwise the default account.
allowGlobalAccountsbooleanfalseLets the call choose one of the project's global accounts. Without it, a global account is used only when connectionId names it.
terminal
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"}}'
200 OK
{ "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.

BodyTypeDefaultWhat it is
connectorIdstringrequiredConnector id.
userIdstringrequiredYour own id for the end user.
endpointstringrequiredPath relative to the connector's API base URL.
methodGET, POST, PUT, PATCH, DELETEGETHTTP method.
queryobjectnoneQuery parameters.
bodyany JSONnoneRequest body.
headersRecord<string, string>noneExtra headers. authorization, proxy-authorization, cookie, and host are dropped.
connectionIduuidnoneOne of the user's accounts, as for execute.
allowGlobalAccountsbooleanfalseAs for execute. A global account also needs its Allow proxy permission, else 403 ACTION_DISABLED.
terminal
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"}'
200 OK
{ "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.

BodyTypeDefaultWhat it is
userIdstringrequiredYour own id for the end user, up to 256 characters.
connectorsstring[]allOnly these connector ids. 1 to 200.
actionsstring[]allOnly these tool ids, or prefixes ending in * (such as slack_*). 1 to 500.
pinnedstring[][]Tool ids listed as full definitions next to the meta tools. At most 20, all in scope.
accountsRecord<string, string>{}Connector id to account id, name, or label, for when a call names no account.
allowGlobalAccountsbooleanfalseLets the agent see and use the project's global accounts. Off, they do not exist for the session.
policy.readOnlybooleanfalseOnly read tools.
policy.maxDataClassstandard, pii, phiphiMost sensitive data class allowed.
policy.allowDisconnectbooleanfalseAdds dexby_disconnect_account.
policy.allowProxybooleanfalseAdds dexby_proxy.
ttlMinutesinteger1440Lifetime, 5 to 43200 minutes.
terminal
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"]}'
201 Created
{
	"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.

PathWhere to get it
:idSession id: data.id from POST /v1/sessions, or Operate → Sessions in the dashboard.
terminal
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.

ParamWhereWhat it is
:idpathSession id, as above.
formatquery, default json-schemajson-schema, or openai-strict for OpenAI strict mode.
terminal
curl "https://api.dexby.ai/v1/sessions/<session-id>/tools?format=openai-strict" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{
	"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.

ParamWhereWhat it is
:idpathSession id, as above.
:namepathTool name from GET /v1/sessions/:id/tools, such as dexby_execute.
argumentsbodyThe model's arguments for the tool.
terminal
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:

200 OK
{
	"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.

PathWhere to get it
:idSession id. The full URL is data.mcpUrl from POST /v1/sessions.
terminal
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.

QueryWhat it is
userIdYour own id for the end user.
terminal
curl "https://api.dexby.ai/v1/connections?userId=user_123" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{
	"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.

BodyTypeDefaultWhat it is
connectorIdstringrequiredConnector id.
userIdstringrequiredYour own id for the end user. Omit it with global.
globalbooleanfalsetrue connects a global account, which every user of the project may use. Give either userId or global.
credentialobjectrequiredtype is oauth2, oauth2_client_credentials, api_key, basic, aws_iam, custom, or none. Unknown fields are rejected.
authConfigstringthe firstAuth config key, from the "Key" field in Build → Auth configs.
namestringnext free nameAccount name, up to 64 characters. The user's first account for a connector is default.
terminal
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.

200 OK
{
	"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 }.

ParamWhereWhat it is
:idpathConnection id (uuid): id from GET /v1/connections?userId=user_123, or Operate → Connections → "Connection ID".
namebodyNew account name. A name the user already has answers 409 NAME_TAKEN.
credentialbodyThe new credential, same shape as on create.
expectedRevisionbodyThe revision you are replacing. A stale revision answers 409 CONFLICT.
terminal
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"}'
200 OK
{ "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.

PathWhere to get it
:idConnection id, as for PATCH.
terminal
curl -X POST "https://api.dexby.ai/v1/connections/<connection-id>/default" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{
	"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.

PathWhere to get it
:idConnection id, as for PATCH.
terminal
curl -X DELETE "https://api.dexby.ai/v1/connections/<connection-id>" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{ "data": { "id": "0190d6a4-5b7e-7c3a-9f10-2b3c4d5e6f70", "erased": true } }

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.

BodyTypeDefaultWhat it is
userIdstringrequiredYour own id for the end user, up to 256 characters.
connectorsstring[]allOffer every auth config of these connector ids.
authConfigsstring[]allOffer these auth configs, by key from Build → Auth configs.
redirectUrlstringnoneWhere the user goes afterward. Must be allowed in Configure → Connect UI, or 400.
expiresInMinutesinteger305 to 1440.
terminal
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"]}'
201 Created
{
	"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.

terminal
curl "https://api.dexby.ai/v1/triggers" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{
	"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.

BodyTypeWhat it is
connectionIduuidRequired. From GET /v1/connections?userId=user_123, or Operate → Connections → "Connection ID".
eventstringRequired. Trigger event id, such as app_mention. From GET /api/catalog/:connectorId → triggers[].id, or the connector page in Build → Catalog.
secretstringManual setup only (such as Slack): the provider's signing secret, up to 512 characters.
terminal
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.

201 Created
{
	"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.

PathWhere to get it
:idTrigger id: id from GET /v1/triggers or create.
terminal
curl -X DELETE "https://api.dexby.ai/v1/triggers/<trigger-id>" \
  -H "Authorization: Bearer $DEXBY_API_KEY"
200 OK
{ "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.

ParamWhereWhat it is
:slugpathEndpoint slug you chose in Distribute → MCP endpoints → New endpoint ("URL slug"). No /v1 route lists endpoints.
:userIdpathYour 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.
terminal
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.

On this page