An integration key holds the credentials CX-Engine uses to connect a customer account to a third-party system (Salesforce, HubSpot, Dynamics, ConnectWise, a webhook…).
All endpoints in this section are workspace-scoped, require the client OAuth scope and act on a single customer account, selected with the customer_account query parameter (see Selecting the customer account).
Headers: Authorization: Bearer {workspace-token}
Credentials are never returned. Secrets are stored encrypted and are not part of any API response. The
has_keysattribute only tells you whether credentials are stored.
#Permissions
| Endpoint | Required permission |
|---|---|
GET /api/integration-keys |
customer-integration.view |
GET /api/integration-keys/{id} |
customer-integration.view |
POST /api/integration-keys |
customer-integration.create |
PUT /api/integration-keys/{id} |
customer-integration.edit |
DELETE /api/integration-keys/{id} |
customer-integration.delete |
The authenticated user must also have access to the selected customer account.
#The integration key object
{
"id": 7,
"uid": "70c7ee70-3e75-4dd3-a728-f435af607db4",
"integration_id": null,
"outsource_provider": "salesforce",
"customer_id": 12,
"keyable_type": "customer",
"keyable_id": 12,
"enabled": true,
"requires_action": false,
"name": "Salesforce production",
"type": "oauth",
"created_at": "2025-02-10T10:12:00.000000Z",
"updated_at": "2025-02-10T10:15:31.000000Z",
"has_keys": true
}
| Field | Description |
|---|---|
outsource_provider |
Connected system: active_campaign, atera, bluerocktel, connectwise, dynamics, glpi, hubspot, neoteem, salesforce, sellsy, webhook |
type |
Authentication type: none, token, app_token, oauth, oauth_pat, oauth_client_credentials, oauth_azure, password, basic, connectwise, oauth_password, header_token |
uid |
Identifier of the OAuth flow, for OAuth-based keys |
requires_action |
true when the OAuth authorization still has to be completed |
enabled |
Whether the key is used |
has_keys |
Whether credentials are stored for this key |
integration_id |
Legacy integration identifier, may be null |
#GET /api/integration-keys
Returns all integration keys of the selected customer as a plain JSON array (not paginated).
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_account |
string | yes | Customer account code |
Response 200 — array of integration key objects
#GET /api/integration-keys/{id}
Returns a single integration key.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_account |
string | yes | Customer account code |
Response 200 — integration key object
Response 404 — the key does not belong to the selected customer
#POST /api/integration-keys
Connects a new integration key to the selected customer. The body must be a JSON object. The key is always attached to the customer selected with customer_account: customer_id, keyable_id, keyable_type and integration_id are ignored if sent.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_account |
string | yes | Customer account code |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
outsource_provider |
string | yes | Connected system (see the table below) |
type |
string | yes | Authentication type, must be one of the types allowed for the provider |
name |
string | yes | Display name (2–255 characters) |
enabled |
boolean | no | Defaults to true |
keys |
object | depends on type |
Credentials (see below) |
Allowed type per provider
outsource_provider |
Allowed type |
|---|---|
active_campaign |
header_token |
atera |
token |
bluerocktel |
password |
connectwise |
connectwise |
dynamics |
oauth_azure, oauth_client_credentials |
glpi |
app_token |
hubspot |
oauth, token |
neoteem |
basic |
salesforce |
oauth |
sellsy |
oauth_pat |
webhook |
none, basic, token, password, oauth_client_credentials, oauth_password |
keys fields per type
type |
Required fields | Optional fields |
|---|---|---|
none |
— | api_url |
token |
— | api_url, access_token, refresh_token, key_placement (header or request_parameter), header_name (required when key_placement is request_parameter), header_prefix |
header_token |
api_url, access_token |
— |
app_token |
api_url, client_id, client_secret |
— |
password, basic |
user_login, user_password |
api_url |
connectwise |
api_url, tenant_id, client_id, user_login, user_password |
— |
oauth_client_credentials |
api_url, client_id, client_secret |
tenant_id, scope |
oauth_password |
api_url, client_id, client_secret, user_login, user_password |
— |
oauth_pat |
client_id, client_secret |
expires_in, expires_at |
oauth_azure |
api_url |
— |
oauth |
— | — |
Example
{
"outsource_provider": "atera",
"type": "token",
"name": "Atera production",
"keys": {
"api_url": "https://app.atera.com/api/v3",
"access_token": "your-atera-api-key"
}
}
Response 201
{
"entity": { "id": 8, "outsource_provider": "atera", "type": "token", "name": "Atera production", "enabled": true, "requires_action": false, "has_keys": true, "...": "..." },
"action": null
}
For OAuth types (oauth, oauth_azure), the key is created with requires_action: true and action describes the authorization to complete: open action.redirect_url in a browser to grant access.
{
"entity": { "id": 9, "outsource_provider": "salesforce", "type": "oauth", "requires_action": true, "...": "..." },
"action": {
"type": "oauth",
"provider": "salesforce",
"uid": "70c7ee70-3e75-4dd3-a728-f435af607db4",
"requires_action": true,
"redirect_url": "https://login.salesforce.com/services/oauth2/authorize?..."
}
}
Response 400 — validation failure: missing or unknown outsource_provider, type not allowed for the provider, missing name, or invalid keys for the type
{
"response": "bad request: please check body parameters.",
"hint": ["The selected type is invalid."]
}
#PUT /api/integration-keys/{id}
Renames, enables or disables an integration key, or replaces its credentials. The body must be a JSON object.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_account |
string | yes | Customer account code |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | no | Display name (2–255 characters) |
enabled |
boolean | no | Enable or disable the key |
keys |
object | no | New credentials, validated against the key's current type (same fields as for creation). They replace the stored credentials. Not accepted for OAuth keys (oauth, oauth_azure): delete and recreate the key instead |
The ownership, provider and type of a key cannot be changed: sending customer_id, keyable_id, keyable_type, integration_id, outsource_provider, type, uid or requires_action returns a 400.
Response 201 — the updated integration key object
Response 400 — validation failure (forbidden field, invalid keys for the key type)
Response 422 — keys sent for an OAuth key
Response 404 — the key does not belong to the selected customer
#DELETE /api/integration-keys/{id}
Deletes an integration key.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_account |
string | yes | Customer account code |
Response 200
{ "response": "element deleted" }
Response 404 — the key does not belong to the selected customer