Skip to navigation

Create an integration

View as Markdown

Registers an integration with credentials you supply, then immediately runs a connection test. The response reflects the test:

  • status: active — the test passed (today, always the case for webhook).
  • status: error with last_error — the test threw. Every provider other than webhook lands here, because their adapters moved to the connected-apps catalogue; last_error says so.
  • status: pending_auth — the test returned “not connected” without an error.

The integration is stored in every case. For OAuth2 providers use GET /api/integrations/oauth/authorize instead, which creates the integration when consent completes. A webhook integration receives pushes at /webhooks/integrations/v2/{inbound_webhook_uuid} with the x-webhook-secret header; no endpoint in this API sets that secret (hasWebhookSecret), and pushes are answered 401 until one is set.

Side effects. Encrypts and stores the credentials; runs the provider test; posts an in-app notification (connected or failed); writes an audit entry (action create, resource integration, credentials redacted).

Idempotency. Not idempotent, but a retry cannot create a duplicate: a second create for the same provider returns 409 while the first integration exists.

Webhook events. audit.log_recorded for webhooks subscribed to it. See Webhooks.

Access

  • Required scope: full. Humans need the admin or owner role.
  • Rate limit: General API (120–600 requests/min per workspace by plan) plus the configuration-mutation limiter — 10 requests/min per workspace, shared with agent and other configuration writes. See Rate limits.
  • Plan: Counts against the integration cap. Every paid plan allows effectively unlimited integrations; a workspace with no active plan is refused.

Authentication

AuthorizationBearer

Workspace API key: jl_ followed by 64 lowercase hex characters, created by the workspace owner in the dashboard (Settings → API Keys) and sent as Authorization: Bearer jl_.... The plaintext is shown once, at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys.

ScopeGET / HEADPOST / PUT / PATCH / DELETEAdmin-only routes
readYesNoNo
writeYesYesNo
fullYesYesYes

Operations restricted to admins or owners reject keys without the full scope with 403, and say so in their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret — that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds. See Authentication.

Request

This endpoint expects an object.
providerenumRequired

Provider to register. Only webhook has a built-in adapter; any other value is stored but its connection test fails (see the description). Unknown values are rejected with 400.

credentialsmap from strings to anyRequired

Provider-specific credentials as a JSON object (use {} for webhook). Encrypted at rest and never returned; responses show ***.

labelstringOptional<=200 characters
Display name shown in the dashboard.
fieldMappingmap from strings to stringsOptional

Source field name → Jelliu contact field (phoneNumber, email, whatsappNumber, name). Applied to inbound webhook payloads. For salesforce, keys must be valid Salesforce field identifiers or the request is rejected with 400.

campaignIdstringOptionalformat: "uuid"

Campaign that inbound contacts are added to. Required in practice for webhook integrations that receive contacts or leads.

Response

Integration stored. Check status and last_error for the connection test result.

dataobject

The full integration record returned by retrieve, create and update: every Integration field plus the columns below. No secret material is returned: credentials is masked, and the OAuth access and refresh tokens and the inbound webhook secret are omitted. hasCredentials and hasWebhookSecret report whether they exist.

Errors

400
Bad Request Error
401
Unauthorized Error
403
Forbidden Error
409
Conflict Error
429
Too Many Requests Error