Skip to content

Connections ​

Routes are relative to <PUBLIC_BASE_URL>; request and response bodies are JSON unless stated otherwise. Authentication, scopes, pagination and the error format are described in the REST API guides.

GET /api/v1/credentials ​

List my connections

The member’s connections, then the organisation’s. Without type, every manageable type; with it, one type, OAuth accounts included (read-only). Never a secret.

Access — Member session or API key with scope connections:read.

Parameters

NameInTypeRequired
typequery"http_generic" | "imap" | "llm_provider" | "gmail_oauth" | "msgraph_oauth" | stringno

Responses

200 — The connections.

FieldTypeRequired
itemsobject[]yes
JSON Schema
json
{
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "type": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "http_generic",
                  "imap",
                  "llm_provider",
                  "gmail_oauth",
                  "msgraph_oauth"
                ]
              },
              { "type": "string" }
            ]
          },
          "name": { "type": "string" },
          "scope": { "type": "string", "enum": [ "member", "org" ] },
          "kind": { "type": "string", "enum": [ "apiKey", "bearer", "basic", "query" ] },
          "integration": { "type": "string" },
          "hint": { "type": "string", "maxLength": 4 },
          "environment": { "type": "string" },
          "capabilities": { "type": "array", "items": { "type": "string" } },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
          }
        },
        "required": [ "id", "type", "name", "scope", "createdAt", "updatedAt" ],
        "additionalProperties": false
      }
    }
  },
  "required": [ "items" ],
  "additionalProperties": false
}

400 — The request does not match its schema.

401 — No valid session or API key (auth.unauthenticated).

403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).

429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.

Error codes — credential.bad_request. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.

POST /api/v1/credentials ​

Create a connection

Stores the secret encrypted and returns only its id. scope: "org" is reserved to administrators. Refused when the instance has no encryption key.

Access — Member session or API key with scope connections:write.

Request body (application/json)

Type : object

JSON Schema
json
{
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "type": { "type": "string", "const": "http_generic" },
        "name": { "type": "string", "minLength": 1, "maxLength": 80 },
        "scope": { "type": "string", "enum": [ "member", "org" ] },
        "data": {
          "oneOf": [
            {
              "type": "object",
              "properties": {
                "kind": { "type": "string", "const": "apiKey" },
                "headerName": { "type": "string", "minLength": 1, "maxLength": 128 },
                "value": { "type": "string", "minLength": 1, "maxLength": 4096 }
              },
              "required": [ "kind", "headerName", "value" ],
              "additionalProperties": false
            },
            {
              "type": "object",
              "properties": {
                "kind": { "type": "string", "const": "bearer" },
                "token": { "type": "string", "minLength": 1, "maxLength": 4096 }
              },
              "required": [ "kind", "token" ],
              "additionalProperties": false
            },
            {
              "type": "object",
              "properties": {
                "kind": { "type": "string", "const": "basic" },
                "username": { "type": "string", "minLength": 1, "maxLength": 256 },
                "password": { "type": "string", "minLength": 1, "maxLength": 4096 }
              },
              "required": [ "kind", "username", "password" ],
              "additionalProperties": false
            },
            {
              "type": "object",
              "properties": {
                "kind": { "type": "string", "const": "query" },
                "paramName": { "type": "string", "minLength": 1, "maxLength": 128 },
                "value": { "type": "string", "minLength": 1, "maxLength": 4096 }
              },
              "required": [ "kind", "paramName", "value" ],
              "additionalProperties": false
            }
          ]
        }
      },
      "required": [ "type", "name", "scope", "data" ]
    },
    {
      "type": "object",
      "properties": {
        "type": { "type": "string" },
        "name": { "type": "string", "minLength": 1, "maxLength": 80 },
        "scope": { "type": "string", "enum": [ "member", "org" ] },
        "data": {
          "type": "object",
          "propertyNames": { "type": "string" },
          "additionalProperties": { "type": "string" }
        }
      },
      "required": [ "type", "name", "scope", "data" ]
    }
  ]
}

Responses

201 — The id of the connection.

FieldTypeRequired
idstring (uuid)yes
JSON Schema
json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    }
  },
  "required": [ "id" ],
  "additionalProperties": false
}

400 — The request does not match its schema.

401 — No valid session or API key (auth.unauthenticated).

403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).

429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.

This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.

Error codes — credential.bad_request, credential.admin_required, credential.encryption_disabled. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.

Example request

json
{
  "type": "http_generic",
  "name": "CRM API",
  "scope": "member",
  "data": { "kind": "bearer", "token": "crm_live_example_token" }
}

Example response (201)

json
{ "id": "0192f1c2-3b4d-7e8f-9a0b-1c2d3e4f5a6b" }

PUT /api/v1/credentials/{id} ​

Rename or replace a connection

Without data, the secret is kept (a plain rename). With it, the secret is replaced entirely, never merged. A connection outside the member’s scope is a 404, never a 403.

Access — Member session or API key with scope connections:write.

Parameters

NameInTypeRequired
idpathstringyes

Request body (application/json)

FieldTypeRequired
namestringno
dataobjectno
JSON Schema
json
{
  "type": "object",
  "properties": {
    "name": { "type": "string", "minLength": 1, "maxLength": 80 },
    "data": {
      "anyOf": [
        {
          "oneOf": [
            {
              "type": "object",
              "properties": {
                "kind": { "type": "string", "const": "apiKey" },
                "headerName": { "type": "string", "minLength": 1, "maxLength": 128 },
                "value": { "type": "string", "minLength": 1, "maxLength": 4096 }
              },
              "required": [ "kind", "headerName", "value" ],
              "additionalProperties": false
            },
            {
              "type": "object",
              "properties": {
                "kind": { "type": "string", "const": "bearer" },
                "token": { "type": "string", "minLength": 1, "maxLength": 4096 }
              },
              "required": [ "kind", "token" ],
              "additionalProperties": false
            },
            {
              "type": "object",
              "properties": {
                "kind": { "type": "string", "const": "basic" },
                "username": { "type": "string", "minLength": 1, "maxLength": 256 },
                "password": { "type": "string", "minLength": 1, "maxLength": 4096 }
              },
              "required": [ "kind", "username", "password" ],
              "additionalProperties": false
            },
            {
              "type": "object",
              "properties": {
                "kind": { "type": "string", "const": "query" },
                "paramName": { "type": "string", "minLength": 1, "maxLength": 128 },
                "value": { "type": "string", "minLength": 1, "maxLength": 4096 }
              },
              "required": [ "kind", "paramName", "value" ],
              "additionalProperties": false
            }
          ]
        },
        {
          "type": "object",
          "propertyNames": { "type": "string" },
          "additionalProperties": { "type": "string" }
        }
      ]
    }
  }
}

Responses

200 — The connection, updated.

FieldTypeRequired
credentialobjectyes
JSON Schema
json
{
  "type": "object",
  "properties": {
    "credential": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "type": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "http_generic",
                "imap",
                "llm_provider",
                "gmail_oauth",
                "msgraph_oauth"
              ]
            },
            { "type": "string" }
          ]
        },
        "name": { "type": "string" },
        "scope": { "type": "string", "enum": [ "member", "org" ] },
        "kind": { "type": "string", "enum": [ "apiKey", "bearer", "basic", "query" ] },
        "integration": { "type": "string" },
        "hint": { "type": "string", "maxLength": 4 },
        "environment": { "type": "string" },
        "capabilities": { "type": "array", "items": { "type": "string" } },
        "createdAt": {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
        }
      },
      "required": [ "id", "type", "name", "scope", "createdAt", "updatedAt" ],
      "additionalProperties": false
    }
  },
  "required": [ "credential" ],
  "additionalProperties": false
}

400 — The request does not match its schema.

401 — No valid session or API key (auth.unauthenticated).

403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).

429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.

Error codes — credential.bad_request, credential.not_found, credential.admin_required, credential.encryption_disabled. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.

DELETE /api/v1/credentials/{id} ​

Delete a connection

Refused (409) while a published workflow references it; details.workflows names them. OAuth accounts are not deleted here but by disconnecting the mailbox.

Access — Member session or API key with scope connections:write.

Parameters

NameInTypeRequired
idpathstringyes

Responses

204 — Deleted.

401 — No valid session or API key (auth.unauthenticated).

403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).

429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.

Error codes — credential.not_found, credential.admin_required, credential.in_use, credential.bad_request. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.

POST /api/v1/credentials/{id}/test ​

Test a connection

Calls the third-party service with the stored secret. Always 200: a revoked token is the result, not an error. HTTP errors remain for an unknown connection (404), a type without a checker (400) and a process that cannot reach integrations (503).

Access — Member session or API key with scope connections:write.

Parameters

NameInTypeRequired
idpathstringyes

Responses

200 — The verdict.

FieldTypeRequired
okbooleanyes
accountstringno
codestringno
statusintegerno
scopesstring[]no
JSON Schema
json
{
  "type": "object",
  "properties": {
    "ok": { "type": "boolean" },
    "account": { "type": "string", "maxLength": 200 },
    "code": { "type": "string" },
    "status": {
      "type": "integer",
      "minimum": -9007199254740991,
      "maximum": 9007199254740991
    },
    "scopes": {
      "maxItems": 20,
      "type": "array",
      "items": { "type": "string", "maxLength": 120 }
    }
  },
  "required": [ "ok" ],
  "additionalProperties": false
}

401 — No valid session or API key (auth.unauthenticated).

403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).

429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.

Error codes — credential.not_found, integration.not_testable, integration.not_wired. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.

GET /api/v1/credentials/{id}/webhook-handshake ​

Read a webhook handshake token

The verification token a service (Notion) posted once to the trigger URL, to paste back in its portal. null while nothing was received. Reserved to whoever may modify the connection.

Access — Member session or API key with scope connections:read.

Parameters

NameInTypeRequired
idpathstringyes

Responses

200 — The token, or null.

FieldTypeRequired
tokenstring | nullyes
JSON Schema
json
{
  "type": "object",
  "properties": { "token": { "anyOf": [ { "type": "string" }, { "type": "null" } ] } },
  "required": [ "token" ],
  "additionalProperties": false
}

401 — No valid session or API key (auth.unauthenticated).

403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).

429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.

Error codes — credential.not_found, credential.bad_request. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.