Skip to main content

OAuth Connections

Looking for the product view?
The Help Center explains this surface as users see it: Connected services.

OAuth authorization flow and connection management.

GET /api/integrations/{id}/connect

Initiate the OAuth authorization flow.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Response:

Redirects to the provider's authorization page (driver-dependent). The server generates and later validates the OAuth state parameter for CSRF protection.

OAuth flow:

  1. The client calls GET /api/integrations/{id}/connect.
  2. The server redirects to the provider's authorization page.
  3. The user authorizes on the provider's site.
  4. The provider redirects back to GET /oauth2/callback?code=...&state=....
  5. The server exchanges the code for tokens and stores the connection.

POST /api/integrations/{id}/connect

Complete the connection by exchanging an authorization code (called by the callback). The body carries the provider's query (the code/state returned to the callback).

Authentication: Required

Response:

Renders the OAuth success page (HTML). The connection is created as a side effect.


GET /oauth2/callback

OAuth callback endpoint, invoked by the provider's redirect. Not called directly by clients.

Authentication: Not required (public endpoint)

Query Parameters:

ParameterTypeDescription
codestringAuthorization code from the provider
statestringState parameter for CSRF validation
error / error_descriptionstringSet when authorization failed

Response:

Redirects to a success or error page.


GET /api/integrations/{id}/connection

Get the current connection for an integration.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Response:

Token/refresh expiry and last-authorization timestamps. The refresh token itself is never returned; a hasRefreshToken boolean indicates whether one is stored. Responds 404 when there is no connection. For per-user integrations this is the caller's connection; for shared integrations, the shared one.

Get an integration’s connectionGET /api/integrations/00000000-0000-4000-8000-000000000001/connection
Token/refresh expiry and last authorization for the caller’s connection (per-user) or the shared connection. The refresh token is never returned; a hasRefreshToken flag indicates whether one is stored. 404 when not connected.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/connection"
}
},
"id": "00000000-0000-4000-8000-000000000002",
"tokenExpiresAt": "2026-01-15T16:20:00.000Z",
"refreshTokenExpiresAt": "2026-01-15T16:20:00.000Z",
"lastAuthorizedAt": "2026-01-15T16:20:00.000Z",
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"ownerId": "admin",
"integrationId": "00000000-0000-4000-8000-000000000001",
"integration": {
"naturalId": "admin:acme-crm",
"driver": {
"id": "api",
"editorComponent": "apiIntegrationEditor",
"extraAuthUriParams": {},
"supportsUpload": false
},
"iconUrl": "/images/icons/plug.svg",
"permissions": {
"write": true,
"edit": true,
"delete": true,
"share": true,
"assignTags": true,
"changeOwner": true
},
"id": "00000000-0000-4000-8000-000000000001",
"name": "Acme CRM",
"slug": "acme-crm",
"description": null,
"category": null,
"type": "api",
"mode": "per-user",
"authType": "apiKey",
"basicTokenAuth": null,
"data": null,
"embedded": false,
"clientId": null,
"clientSecret": null,
"apiKey": "encrypted:iv:0000000000000000",
"apiKeyLocation": "header",
"apiKeyName": "X-API-Key",
"headers": {},
"scope": null,
"apiBaseUri": "https://api.acme.example.com/v1",
"authUri": null,
"tokenUri": null,
"revocationUri": null,
"imageUrl": null,
"libraryId": null,
"mailTenantId": null,
"ownerId": "admin",
"shared": false,
"folderId": null,
"source": null,
"sourceId": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"icon": null
},
"hasRefreshToken": true
}
Captured from the API examples test suite; ids and timestamps are normalized.

DELETE /api/integrations/{id}/connection

Disconnect and revoke the connection.

Authentication: Required

Permissions: The caller must own the connection (or be a superuser)

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Response:

Revokes the tokens with the provider (when revocationUri is configured) and deletes the connection. Responds 200 with an empty body.

DisconnectDELETE /api/integrations/00000000-0000-4000-8000-000000000001/connection
Revokes the tokens with the provider (when revocationUri is configured) and deletes the connection. Responds 200 with an empty body.
Response · 200 · no body
Captured from the API examples test suite; ids and timestamps are normalized.
Impact

Disconnecting may break libraries, jobs, or other features that depend on the integration until it is reconnected.


GET /api/integration-connections

List the caller's connections across all integrations.

Authentication: Required

Response:

A HAL collection under _embedded["inf:connection"], each connection embedding its integration. Always scoped to the caller: even a superuser or impersonator sees only their own connections (and an impersonator sees none).

List my connectionsGET /api/integration-connections
The caller’s own connections across all integrations, each embedding its integration. Always scoped to the caller: even a superuser or impersonator sees only their own.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/integration-connections"
}
},
"start": 0,
"count": 1,
"total": 1,
"_embedded": {
"inf:connection": [
{
"_links": {
"self": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/connection"
}
},
"id": "00000000-0000-4000-8000-000000000002",
"integrationId": "00000000-0000-4000-8000-000000000001",
"ownerId": "admin",
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"_embedded": {
"inf:integration": {
"_links": {
"self": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001"
},
"inf:integration-share": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/shares/{principalId}",
"templated": true
},
"inf:icon": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/icon"
},
"inf:connect": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/connect"
},
"inf:connection": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/connection"
},
"inf:request": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/request"
},
"inf:favorite": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/favorite"
},
"inf:integration-owner": {
"href": "https://informer.example.com/api/integrations/undefined%3Aacme-crm/owner"
},
"inf:integration-shares": {
"href": "https://informer.example.com/api/integrations/undefined%3Aacme-crm/shares"
}
},
"naturalId": "undefined:acme-crm",
"driver": {
"id": "missing",
"extraAuthUriParams": {},
"supportsUpload": false
},
"iconUrl": "/images/icons/plug.svg",
"permissions": {
"write": true,
"edit": true,
"delete": true,
"share": true,
"assignTags": true,
"changeOwner": true
},
"id": "00000000-0000-4000-8000-000000000001",
"name": "Acme CRM",
"slug": "acme-crm",
"description": null,
"imageUrl": null,
"icon": null
}
}
}
]
}
}
Captured from the API examples test suite; ids and timestamps are normalized.

POST /api/integrations/{id}/request

Proxy an authenticated request through an integration. The integration applies its stored credentials (OAuth tokens, API key, etc.) and refreshes tokens as needed.

Authentication: Required

Permissions: A valid connection (for connection-based auth types)

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Request Body:

FieldTypeRequiredDescription
urlstringYesRelative (combined with apiBaseUri) or same-origin absolute URL
methodstringNoGET (default), POST, PUT, PATCH, DELETE, HEAD, OPTIONS
headersobjectNoAdditional request headers
paramsobjectNoURL query parameters
dataanyNoRequest body
encodingstringNobase64 to send a binary data body (decoded before sending)

Example:

{ "method": "GET", "url": "/files", "params": { "pageSize": 10 } }

Response:

The proxied response from the external API, streamed back with its status and headers. (Calls the external service, so it is not exercised in the captured examples.)

Same-origin only

To prevent SSRF and credential exfiltration, an absolute url is accepted only when it shares the integration's configured origin and falls under its base path. Otherwise use a relative URL.


GET /api/integrations/{id}/request/{path*}

Read-only (GET) proxy variant addressed by path, safe for whitelisted external link sharing.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug
pathstringRelative API path (query string is forwarded)

Example:

GET /api/integrations/admin:acme-crm/request/files?pageSize=10

Response:

The proxied response from the external API.