Skip to main content

Core CRUD

Basic integration creation, retrieval, update, and deletion operations.

GET /api/integrations

List non-embedded integrations.

Authentication: Required

Query Parameters:

ParameterTypeDefaultDescription
qstring-Full-text search (name, description)
supportsUploadboolean-Filter by the driver's upload capability

Response:

A paginated HAL collection under _embedded["inf:integration"]. Embedded integrations (created automatically for libraries) are excluded.

Search and page through integrationsGET /api/integrations
A paginated HAL collection under _embedded["inf:integration"]; excludes embedded (library-owned) integrations. q matches name and description; supportsUpload filters by driver capability.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/integrations"
}
},
"start": 0,
"count": 1,
"total": 1,
"_embedded": {
"inf:integration": [
{
"_links": {
"self": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm"
},
"inf:integration-share": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/shares/{principalId}",
"templated": true
},
"inf:icon": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/icon"
},
"inf:connect": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/connect"
},
"inf:connection": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/connection"
},
"inf:request": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/request"
},
"inf:favorite": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/favorite"
},
"inf:integration-owner": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/owner"
},
"inf:integration-shares": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/shares"
}
},
"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": "Acme CRM REST API",
"category": "crm",
"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
}
]
}
}
Captured from the API examples test suite; ids and timestamps are normalized.

GET /api/integrations-list

A flat array of readable integrations with tags, sharing, and permissions. Used by integration galleries and pickers. Supports ETags.

Authentication: Required

Response:

List integrationsGET /api/integrations-list
A flat array with tags, sharing, and per-integration permissions. Used by galleries and pickers.
Response · 200
[
{
"id": "00000000-0000-4000-8000-000000000001",
"slug": "acme-crm",
"name": "Acme CRM",
"type": "api",
"description": "Acme CRM REST API",
"category": "crm",
"shared": false,
"embedded": false,
"imageUrl": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"ownerId": "admin",
"folderId": null,
"username": "admin",
"teamName": null,
"favorite": false,
"naturalId": "admin:acme-crm",
"permissions": {
"write": true,
"edit": true,
"delete": true,
"share": true,
"assignTags": true,
"changeOwner": true
},
"ownerName": "acme Administrator",
"tags": [],
"sharing": []
}
]
Captured from the API examples test suite; ids and timestamps are normalized.
note

iconUrl appears on an entry only when a custom icon has been uploaded for that integration: it is the icon route URL with a cache-busting timestamp. It is absent otherwise.


GET /api/integrations/{id}

Get a single integration.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Response:

Get a single integrationGET /api/integrations/admin:acme-crm
clientSecret and apiKey are never returned.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm"
},
"inf:integration-share": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/shares/{principalId}",
"templated": true
},
"inf:icon": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/icon"
},
"inf:connect": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/connect"
},
"inf:connection": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/connection"
},
"inf:request": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/request"
},
"inf:favorite": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/favorite"
},
"inf:integration-owner": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/owner"
},
"inf:integration-shares": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/shares"
}
},
"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": "Acme CRM REST API",
"category": "crm",
"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
}
Captured from the API examples test suite; ids and timestamps are normalized.
Sensitive data

clientSecret and apiKey are stored encrypted and are never returned in clear text.


POST /api/integrations

Create a new integration.

Authentication: Required

Permissions: Requires permission.integrations.create

Request Body:

FieldTypeRequiredDescription
idstring (UUID)NoPre-generated id
namestringYesIntegration name
typestringYesIntegration-driver type (e.g. api, googledrive, gmail, onedrive)
apiBaseUristringYesBase URL for API requests
authTypestringNooauth2 (default), apiKey, basic, bearer, none, tokenExchange
modestringNoper-user (default) or shared
categorystringNoCategory (e.g. storage, crm)
descriptionstringNoDescription
scopestringNoOAuth scopes (space-separated)
authUri / tokenUri / revocationUristringNoOAuth endpoints
clientId / clientSecretstringNoOAuth client credentials
basicTokenAuthbooleanNoUse Basic auth for token requests
apiKeystringNoAPI key (for authType: apiKey)
apiKeyLocationstringNoheader or query
apiKeyNamestringNoKey parameter/header name
imageUrlstringNoIcon URL
headersobjectNoCustom headers sent with proxied requests (variable expansion, below)
dataobjectNoDriver-specific configuration
sharedbooleanNoShare with the tenant (default false)

Custom headers with variable expansion

headers values support ${...} expansion, resolved per request so each user's proxied requests carry their own identity:

VariableResolves to
${user.username} / ${user.displayName} / ${user.email}The authenticated user
${user.<fieldName>}A custom user field
${tenant.id} / ${tenant.<fieldName>}The current tenant
{ "headers": { "X-User-Email": "${user.email}", "X-Tenant": "${tenant.id}" } }

Example - OAuth 2.0:

{
"name": "Google Drive - Engineering",
"type": "googledrive",
"authType": "oauth2",
"scope": "https://www.googleapis.com/auth/drive.readonly",
"authUri": "https://accounts.google.com/o/oauth2/v2/auth",
"tokenUri": "https://oauth2.googleapis.com/token",
"apiBaseUri": "https://www.googleapis.com/drive/v3",
"clientId": "123456789-abcdefg.apps.googleusercontent.com",
"clientSecret": "GOCSPX-your-secret"
}

Example - API key:

{
"name": "Acme CRM",
"type": "api",
"authType": "apiKey",
"apiKey": "YOUR_API_KEY",
"apiKeyLocation": "header",
"apiKeyName": "X-API-Key",
"apiBaseUri": "https://api.acme.example.com/v1"
}

Response:

Responds 201 Created with the integration and a Location header. Stored secrets come back only as encrypted blobs.

Create an integrationPOST /api/integrations
type is an integration-driver id (api is the generic REST type). apiBaseUri is required. authType is one of oauth2, apiKey, basic, bearer, none, tokenExchange. Secrets (clientSecret, apiKey) are stored encrypted and never returned. Responds 201 with a Location header.
Request body
{
"name": "Acme CRM",
"type": "api",
"category": "crm",
"description": "Acme CRM REST API",
"authType": "apiKey",
"apiKey": "YOUR_API_KEY",
"apiKeyLocation": "header",
"apiKeyName": "X-API-Key",
"apiBaseUri": "https://api.acme.example.com/v1"
}
Response · 201
{
"_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/admin%3Aacme-crm/owner"
},
"inf:integration-shares": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/shares"
}
},
"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",
"headers": {},
"tenant": "acme",
"name": "Acme CRM",
"type": "api",
"category": "crm",
"description": "Acme CRM REST API",
"authType": "apiKey",
"apiKey": "encrypted:iv:0000000000000000",
"apiKeyLocation": "header",
"apiKeyName": "X-API-Key",
"apiBaseUri": "https://api.acme.example.com/v1",
"mode": "per-user",
"shared": false,
"ownerId": "admin",
"updatedAt": "2026-01-15T16:20:00.000Z",
"createdAt": "2026-01-15T16:20:00.000Z",
"slug": "acme-crm",
"data": null,
"clientId": null,
"clientSecret": null,
"scope": null,
"authUri": null,
"tokenUri": null,
"revocationUri": null,
"imageUrl": null,
"basicTokenAuth": null,
"embedded": false,
"libraryId": null,
"mailTenantId": null,
"folderId": null,
"source": null,
"sourceId": null
}
Captured from the API examples test suite; ids and timestamps are normalized.

PUT /api/integrations/{id}

Update an existing integration. Accepts the same fields as create (all optional). Omit clientSecret/apiKey to leave the stored value unchanged.

Authentication: Required

Permissions: Requires integration:write

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Example:

{ "description": "Acme CRM REST API (v1)" }

Response:

Responds 200 with the updated integration.

Update an integrationPUT /api/integrations/00000000-0000-4000-8000-000000000001
Request body
{
"description": "Acme CRM REST API (v1)"
}
Response · 200
{
"_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/admin%3Aacme-crm/owner"
},
"inf:integration-shares": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/shares"
}
},
"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": "Acme CRM REST API (v1)",
"category": "crm",
"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
}
Captured from the API examples test suite; ids and timestamps are normalized.

DELETE /api/integrations/{id}

Delete an integration.

Authentication: Required

Permissions: Requires integration:delete

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Response:

Responds 200 with an empty body.

Delete an integrationDELETE /api/integrations/00000000-0000-4000-8000-000000000001
Permanently removes the integration and its connections. Responds 200 with an empty body.
Response · 200 · no body
Captured from the API examples test suite; ids and timestamps are normalized.
Cascade delete

Deleting an integration permanently removes its connections and may break libraries or jobs that depend on it.


GET /api/integrations/{id}/owner

Get the current owner of an integration.

Authentication: Required

Response:

The owning principal (user or team), with the user or team embedded.

Get an integration’s ownerGET /api/integrations/00000000-0000-4000-8000-000000000001/owner
The owning principal (user or team), with the user or team embedded.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/integrations/00000000-0000-4000-8000-000000000001/owner"
}
},
"id": "admin",
"userId": "admin",
"teamId": null,
"tenant": "acme",
"_embedded": {
"inf:user": {
"_links": {
"self": {
"href": "https://informer.example.com/api/users/admin"
},
"inf:memberships": {
"href": "https://informer.example.com/api/users/admin/memberships"
},
"inf:avatar-upload": {
"href": "https://informer.example.com/api/users/admin/_upload/{uploadId}/avatar-upload",
"templated": true
},
"inf:password": {
"href": "https://informer.example.com/api/users/admin/password"
},
"inf:feed": {
"href": "https://informer.example.com/api/users/admin/feed"
},
"inf:viewed-feed": {
"href": "https://informer.example.com/api/users/admin/_markFeedViewed"
},
"inf:superuser": {
"href": "https://informer.example.com/api/users/admin/superuser"
}
},
"permissions": {
"changeDomain": false,
"changeProfile": true,
"changePassword": true,
"delete": false,
"edit": true,
"reassign": true,
"superuser": true,
"enable": true,
"changeTheme": true,
"lock": true,
"setGlobalPermissions": true,
"manageLogin": true
},
"domain": "local",
"username": "admin",
"displayName": "acme Administrator",
"familyName": "Administrator",
"givenName": "acme",
"middleName": null,
"email": null,
"data": null,
"superuser": true,
"timezone": "America/New_York",
"settings": {
"log": {
"log": false,
"info": false,
"warn": false,
"debug": false,
"error": true,
"remote": false
}
},
"enabled": true,
"source": null,
"sourceId": null,
"lastViewedFeed": null,
"tenant": "acme",
"globalPermissions": {
"ai": false,
"jobCreation": true,
"viewAllTeams": true,
"viewAllUsers": true,
"painlessScriptCreation": true
},
"userFields": {},
"locked": false,
"lockedAt": null,
"loginAttempts": 0,
"passwordSetAt": "2026-01-15T16:20:00.000Z",
"passwordExpiresAt": "2026-01-15T16:20:00.000Z",
"forgotPasswordRequestTime": null,
"mfa": null,
"mfaConfig": {},
"aiMessage": null,
"aiConsent": false,
"hasSharedDatasources": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"initials": "NA",
"colorIndex": 4,
"avatarColor": {
"background": "#81C784",
"text": "#1B5E20"
},
"managesPassword": true
}
}
}
Captured from the API examples test suite; ids and timestamps are normalized.

PUT /api/integrations/{id}/owner

Change the owner.

Authentication: Required

Permissions: Requires integration:changeOwner

Request Body:

A principal lookup: { "userId": "<username>" } or { "teamId": "<team-id>" }.

Response:

Responds 200 with the updated integration and a Location header.

Reassign an integration’s ownerPUT /api/integrations/00000000-0000-4000-8000-000000000001/owner
Body is a principal lookup: { userId } or { teamId } (not ownerId). Responds 200 with a Location header.
Request body
{
"userId": "admin"
}
Response · 200
{
"_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/admin%3Aacme-crm/owner"
},
"inf:integration-shares": {
"href": "https://informer.example.com/api/integrations/admin%3Aacme-crm/shares"
}
},
"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": "Acme CRM REST API (v1)",
"category": "crm",
"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
}
Captured from the API examples test suite; ids and timestamps are normalized.

GET /api/integrations/{id}/account

Get the connected provider account.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Response:

Driver-specific. An OAuth integration returns the connected account once connected (and 400 if it is not connected); the generic api driver has no account concept and returns null.

Get the connected accountGET /api/integrations/00000000-0000-4000-8000-000000000001/account
Driver-specific. OAuth integrations return the connected provider account once connected (otherwise 400); the generic api driver has no account and returns null.
Response · 200 · no body
Captured from the API examples test suite; ids and timestamps are normalized.

GET /api/integrations/{id}/icon

Get the integration's custom icon.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringIntegration id or slug

Response:

The icon image bytes, or 404 when no custom icon has been uploaded. (Binary, not shown.)


PUT /api/integrations/{id}/icon

Upload a custom icon.

Authentication: Required

Permissions: Requires integration:write

Request Body:

FieldTypeDescription
uploadstringUpload id from a prior upload session
progressstringProgress identifier

Response:

Responds 201 Created with the stored file and a Location header.


DELETE /api/integrations/{id}/icon

Remove the custom icon.

Authentication: Required

Permissions: Requires integration:write

Response:

Responds 200 with an empty body.

Remove the custom iconDELETE /api/integrations/00000000-0000-4000-8000-000000000001/icon
Responds 200 with an empty body (no-op when no custom icon is set).
Response · 200 · no body
Captured from the API examples test suite; ids and timestamps are normalized.