VendoVendo Docs
ReferenceHTTP API

Connections (runtime)

List bound and supported connections for the calling deployment.

GET /api/deployments/me/connections

Returns the joined list of bound and supported connections for the calling deployment's app. This is the endpoint the SDK's connections.list() wraps.

Auth

App Key only (vendo_sk_* issued at deploy time). Connection-scoped keys are rejected (401 "Invalid or revoked token"). Identity JWTs are rejected before any verification (401 "Missing or invalid Bearer token") because the route hard-checks startsWith("vendo_sk_").

Request

GET /api/deployments/me/connections HTTP/1.1
Host: vendo.run
Authorization: Bearer vendo_sk_…

Query parameters

ParamTypeDescription
sandbox"1"Optional. When set, strips credential payloads for "exclusive" providers (used by customize-mode sandboxes).

Response: 200 OK

{
  "connections": [
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "slug": "openai",
      "display_name": "OpenAI",
      "category": "llm",
      "profile": "vendo_managed_pool",
      "status": "connected",
      "api_key": "vendo_sk_…",
      "base_url": "https://openai-proxy.vendo.run/v1",
      "metadata": { },
      "context": null,
      "setup_url": null,
      "error_message": null,
      "env_bootstrap": { "vars": [], "restart": "none" },
      "exclusive": false,
      "logo_url": "https://vendo.run/logos/openai.svg",
      "brand_color": "#10A37F",
      "docs_url": "https://platform.openai.com/docs"
    },
    {
      "id": null,
      "slug": "telegram",
      "display_name": "Telegram",
      "category": "messaging",
      "profile": "byok_static",
      "status": "available",
      "api_key": null,
      "base_url": null,
      "metadata": {},
      "context": null,
      "setup_url": "https://vendo.run/connections/connect/telegram?app=…",
      "error_message": null,
      "env_bootstrap": null,
      "exclusive": true,
      "logo_url": "https://vendo.run/logos/telegram.svg",
      "brand_color": "#229ED9",
      "docs_url": "https://core.telegram.org/bots"
    }
  ]
}

Status mapping

Mapping from connections.status (DB) → response status:

DB statusResponse statusMeaning
activeconnectedBound and healthy
needs_reauthneeds_reauthOAuth token expired — render a "Reconnect" affordance
errorerrorProvider rejected credential (see error_message)
revoked(filtered out)Falls back to available if the slug is in the tool's supported list
(no binding)availableTenant has not connected this provider yet

pending_setup is part of the canonical ConnectionStatus union elsewhere in the SDK but never appears in this response — the builder filters it out.

Fields

FieldTypeNotes
idstring | nullUUID of the binding's connections row. null on available entries (no DB row exists yet).
slugstringIntegration slug (e.g. openai, telegram)
display_namestringCatalog display name; falls back to the binding's stored display name when present
categorystringllm, messaging, tts, etc.
profilestringvendo_managed_pool, byok_static, user_oauth, oauth_app_install, webhook_inbound, composio_managed
statusstringOne of connected, available, needs_reauth, error
api_keystring | nullOnly set when profile == "vendo_managed_pool" — the same vendo_sk_* the app already has, exposed here so clients that pin the bearer per provider can use a uniform shape
base_urlstring | nullOnly set when profile == "vendo_managed_pool" — the matching {provider}-proxy.vendo.run URL
metadataobjectPer-binding metadata; for connections with a decrypted credential, the route merges metadata.credential.<env_var> so SDK consumers can read it directly
contextobject | nullFlattened from metadata.context[slug] by the SDK-surface normalizer. Discovery providers (e.g. Supabase project ref, Instagram user id) expose per-slug context here. null for non-discovery providers and available entries.
setup_urlstring | nullWhere to send the user to connect this provider; only set on available entries
error_messagestring | nullHuman-readable error when status == "error" or needs_reauth
env_bootstrapobject | nullEnv vars the deploy worker would inject for this integration. Shape: { vars: [{ name, value_from }], restart: "gateway" | "none" }. null when unset.
exclusiveboolean | undefinedtrue when only one running deployment can use this credential at a time (e.g. Telegram). Sandbox callers skip env-bootstrap for exclusive connections.
logo_urlstring | undefinedAbsolutized integration logo URL
brand_colorstring | undefinedHex brand color
docs_urlstring | undefinedIntegration docs link

There is no branding object. logo_url, brand_color, and docs_url are top-level fields.

The full response is built in web/src/lib/connections/list-for-deployment.ts.

Which slugs appear

Tools with surface_all_connections: true in apps_catalog (e.g. Hermes) get every enabled integration in the catalog. Other tools see only the slugs listed in their apps_catalog.supported_connections array. Any bound connection whose slug isn't in either list is still appended at the end of the response so legacy bindings don't disappear.

This endpoint is single-shot, not a stream. Connections that change while your app is running won't update the response from a previous call. Subscribe to GET /api/deployments/me/events for live updates, or restart the container to re-read.

Errors

StatusBodyCause
401{ "error": { "message": "Missing or invalid Bearer token" } }No Bearer, token doesn't start with vendo_sk_, or token is a JWT
401{ "error": { "message": "Invalid or revoked token" } }Connection-scoped key, revoked key, or unknown app
500{ "error": { "message": "Internal server error" } }Vendo bug
  • SDK referenceconnections.list() and connections.get() wrap this endpoint
  • Events — live connection-state changes
  • Apps — change which connection backs a deployed app

On this page