Integrations
Every call needs Authorization: Bearer <key>. 23 calls:
- List integrations:
GET /v1/integrations/catalog - List integration connections:
GET /v1/integrations/connections - Get an integration connection:
GET /v1/integrations/connections/:id - Update an integration connection:
PATCH /v1/integrations/connections/:id - Disconnect an integration:
DELETE /v1/integrations/connections/:id - Import contacts from the provider:
POST /v1/integrations/connections/:id/backfill - Make bubbl3 the texting provider:
PUT /v1/integrations/connections/:id/conversation-provider - A clinic connection's data rule and webhook:
GET /v1/integrations/connections/:id/healthcare - List a connection's inboxes:
GET /v1/integrations/connections/:id/inboxes - List a Meta Page's lead forms:
GET /v1/integrations/connections/:id/lead-forms - Choose a Meta Page's lead forms:
PUT /v1/integrations/connections/:id/lead-forms - Get a connection's field mappings:
GET /v1/integrations/connections/:id/mappings - Replace a connection's field mappings:
PUT /v1/integrations/connections/:id/mappings - Count the contacts a filter would import:
POST /v1/integrations/connections/:id/preview - List an agency connection's locations:
GET /v1/integrations/connections/:id/sub-accounts - Connect a location of an agency connection:
POST /v1/integrations/connections/:id/sub-accounts - List a connection's sync runs:
GET /v1/integrations/connections/:id/sync-runs - Test an integration connection:
POST /v1/integrations/connections/:id/test - Start connecting an integration:
GET /v1/integrations/:provider/authorize - OAuth callback:
GET /v1/integrations/:provider/callback - Provider uninstall callback:
DELETE /v1/integrations/:provider/callback - Finish connecting an integration:
POST /v1/integrations/:provider/complete - Connect an integration with an API key:
POST /v1/integrations/:provider/connect
List integrations
GET /v1/integrations/catalog
Every provider bubbl3 integrates with and whether it can be connected here. coming_soon until it is built and configured.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].app_url | string (uri) or null | For apps customers add in the provider (the bubbl3 Zapier app): its invite link, once offered. |
data[].auth_kind | enum | One of: oauth2, oauth2_pkce, api_key, token, webhook_only, none. |
data[].authorize_account | object | For one-click providers whose consent page is on the customer’s own site (Shopify’s store), once offered: what to ask for before connecting. Pass it as account to /v1/integrations/{provider}/authorize. |
data[].authorize_account.hint | string | |
data[].authorize_account.label | string | |
data[].capabilities | object | |
data[].capabilities.conversation_provider | boolean | |
data[].capabilities.conversions | boolean | |
data[].capabilities.import_contacts | boolean | |
data[].capabilities.log_messages | boolean | |
data[].capabilities.new_lead_events | enum | One of: webhook, poll, stream, none. |
data[].capabilities.writeback | boolean | |
data[].category | string | |
data[].docs_slug | string | |
data[].guide_url | string (uri) or null | For "Via webhook" tiles, set up with a lead source, the public API or a webhook: the docs page that shows how. |
data[].healthcare | boolean | |
data[].key | string | Provider key, e.g. gohighlevel. |
data[].key_fields | object[] | For providers connected with the customer’s own API key (ActiveCampaign, Copper, Freshsales, Lofty), once offered: what to ask for, in order. Post them to /v1/integrations/{provider}/connect. |
data[].key_fields[].hint | string | |
data[].key_fields[].label | string | |
data[].key_fields[].name | enum | One of: api_key, account_url, user_email, domain, account_id, api_secret, username, password. |
data[].name | string | |
data[].status | enum | coming_soon until the provider is built and its credentials are configured. One of: available, beta, coming_soon, partner_approval. |
data[].tier | enum | One of: 1, 2, 3, 3b, guide. |
data[].tile_label | string |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List integration connections
GET /v1/integrations/connections
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].account_type | enum | agency: an agency-level install whose locations are connected one by one. One of: agency, location. |
data[].consent_attested_at | string (date-time) or null | When the consent attestation was confirmed. Null if made before it was asked. |
data[].consent_attested_by | string or null | Who confirmed it: user:<id> for a member, api_key:<id> for an API key. |
data[].consent_field | string or null | |
data[].consent_mode | enum | One of: crm_field, web_form, existing_relationship, not_sure. |
data[].conversation_provider | object or null | bubbl3 as the texting provider for this CRM account, if it was ever set up. |
data[].conversation_provider.eligibility | enum | Inbox channels (HubSpot): not_eligible when the CRM refused the channel for this account; bubbl3 then logs texts on the contact instead. One of: unknown, eligible, not_eligible. |
data[].conversation_provider.eligibility_reason | string or null | Why the CRM refused the channel. |
data[].conversation_provider.enabled | boolean | |
data[].conversation_provider.inbox_id | string or null | Inbox channels (HubSpot): the CRM inbox bubbl3’s channel is connected to. |
data[].conversation_provider.line_id | string or null | Line id (ln_...). |
data[].conversation_provider.pool_id | string or null | Pool id (pool_...). |
data[].conversation_provider.updated_at | string (date-time) | ISO 8601 timestamp. |
data[].created_at | string (date-time) | ISO 8601 timestamp. |
data[].external_account_id | string | |
data[].external_account_name | string or null | |
data[].form_ids | string[] or null | For a Meta Page: the lead forms whose leads come in; empty for every form. Null for the rest. |
data[].id | string | Integration connection id (int_...). |
data[].import_filter | object | |
data[].import_filter.list | string | Up to 200 characters. |
data[].import_filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
data[].import_filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
data[].import_filter.pipeline | string | Up to 200 characters. |
data[].import_filter.since | string (date-time) | ISO 8601 timestamp. |
data[].import_filter.stage | string | Up to 200 characters. |
data[].import_filter.tag | string | Up to 200 characters. |
data[].last_error | string or null | |
data[].last_sync_at | string (date-time) or null | ISO 8601 timestamp. |
data[].lead_source_id | string or null | For a Meta Page: the lead source its leads go through, where its workflow, consent mode and labels are set (/v1/inbound-sources/{id}). Null for the rest. |
data[].parent_id | string or null | The agency connection this location was connected through, if any. |
data[].polling | object or null | For CRMs bubbl3 checks for changes instead of receiving webhooks (Salesforce): the last check. Null for the rest. |
data[].polling.last_changes | integer | New or changed records the last check found. From 0 to 9007199254740991. |
data[].polling.last_error | string or null | |
data[].polling.last_polled_at | string (date-time) or null | ISO 8601 timestamp. |
data[].provider | string | Provider key, e.g. gohighlevel. |
data[].scopes | string[] | |
data[].status | enum | One of: connected, needs_attention, disconnected. |
data[].updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Get an integration connection
GET /v1/integrations/connections/:id
Includes how many bubbl3 opt-outs are waiting to be written back to the CRM. They are delivered once the connection works again.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
account_type | enum | agency: an agency-level install whose locations are connected one by one. One of: agency, location. |
consent_attested_at | string (date-time) or null | When the consent attestation was confirmed. Null if made before it was asked. |
consent_attested_by | string or null | Who confirmed it: user:<id> for a member, api_key:<id> for an API key. |
consent_field | string or null | |
consent_mode | enum | One of: crm_field, web_form, existing_relationship, not_sure. |
conversation_provider | object or null | bubbl3 as the texting provider for this CRM account, if it was ever set up. |
conversation_provider.eligibility | enum | Inbox channels (HubSpot): not_eligible when the CRM refused the channel for this account; bubbl3 then logs texts on the contact instead. One of: unknown, eligible, not_eligible. |
conversation_provider.eligibility_reason | string or null | Why the CRM refused the channel. |
conversation_provider.enabled | boolean | |
conversation_provider.inbox_id | string or null | Inbox channels (HubSpot): the CRM inbox bubbl3’s channel is connected to. |
conversation_provider.line_id | string or null | Line id (ln_...). |
conversation_provider.pool_id | string or null | Pool id (pool_...). |
conversation_provider.updated_at | string (date-time) | ISO 8601 timestamp. |
created_at | string (date-time) | ISO 8601 timestamp. |
external_account_id | string | |
external_account_name | string or null | |
form_ids | string[] or null | For a Meta Page: the lead forms whose leads come in; empty for every form. Null for the rest. |
id | string | Integration connection id (int_...). |
import_filter | object | |
import_filter.list | string | Up to 200 characters. |
import_filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
import_filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
import_filter.pipeline | string | Up to 200 characters. |
import_filter.since | string (date-time) | ISO 8601 timestamp. |
import_filter.stage | string | Up to 200 characters. |
import_filter.tag | string | Up to 200 characters. |
last_error | string or null | |
last_sync_at | string (date-time) or null | ISO 8601 timestamp. |
lead_source_id | string or null | For a Meta Page: the lead source its leads go through, where its workflow, consent mode and labels are set (/v1/inbound-sources/{id}). Null for the rest. |
parent_id | string or null | The agency connection this location was connected through, if any. |
pending_opt_out_writebacks | integer | bubbl3 opt-outs queued for this CRM and not delivered yet. From 0 to 9007199254740991. |
polling | object or null | For CRMs bubbl3 checks for changes instead of receiving webhooks (Salesforce): the last check. Null for the rest. |
polling.last_changes | integer | New or changed records the last check found. From 0 to 9007199254740991. |
polling.last_error | string or null | |
polling.last_polled_at | string (date-time) or null | ISO 8601 timestamp. |
provider | string | Provider key, e.g. gohighlevel. |
scopes | string[] | |
status | enum | One of: connected, needs_attention, disconnected. |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Update an integration connection
PATCH /v1/integrations/connections/:id
Sets how consent is read and which contacts import. A consent mode other than not_sure needs the compliance area at full access, and confirms consent for the contacts this connection imported as unknown.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
consent_field | string or null | No | Up to 200 characters. |
consent_mode | enum | No | A mode other than not_sure also needs the compliance area at full access. One of: crm_field, web_form, existing_relationship, not_sure. |
import_filter | object | No | |
import_filter.list | string | No | Up to 200 characters. |
import_filter.object | enum | No | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
import_filter.owner | string | No | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
import_filter.pipeline | string | No | Up to 200 characters. |
import_filter.since | string (date-time) | No | ISO 8601 timestamp. |
import_filter.stage | string | No | Up to 200 characters. |
import_filter.tag | string | No | Up to 200 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
account_type | enum | agency: an agency-level install whose locations are connected one by one. One of: agency, location. |
consent_attested_at | string (date-time) or null | When the consent attestation was confirmed. Null if made before it was asked. |
consent_attested_by | string or null | Who confirmed it: user:<id> for a member, api_key:<id> for an API key. |
consent_field | string or null | |
consent_mode | enum | One of: crm_field, web_form, existing_relationship, not_sure. |
conversation_provider | object or null | bubbl3 as the texting provider for this CRM account, if it was ever set up. |
conversation_provider.eligibility | enum | Inbox channels (HubSpot): not_eligible when the CRM refused the channel for this account; bubbl3 then logs texts on the contact instead. One of: unknown, eligible, not_eligible. |
conversation_provider.eligibility_reason | string or null | Why the CRM refused the channel. |
conversation_provider.enabled | boolean | |
conversation_provider.inbox_id | string or null | Inbox channels (HubSpot): the CRM inbox bubbl3’s channel is connected to. |
conversation_provider.line_id | string or null | Line id (ln_...). |
conversation_provider.pool_id | string or null | Pool id (pool_...). |
conversation_provider.updated_at | string (date-time) | ISO 8601 timestamp. |
created_at | string (date-time) | ISO 8601 timestamp. |
external_account_id | string | |
external_account_name | string or null | |
form_ids | string[] or null | For a Meta Page: the lead forms whose leads come in; empty for every form. Null for the rest. |
id | string | Integration connection id (int_...). |
import_filter | object | |
import_filter.list | string | Up to 200 characters. |
import_filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
import_filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
import_filter.pipeline | string | Up to 200 characters. |
import_filter.since | string (date-time) | ISO 8601 timestamp. |
import_filter.stage | string | Up to 200 characters. |
import_filter.tag | string | Up to 200 characters. |
last_error | string or null | |
last_sync_at | string (date-time) or null | ISO 8601 timestamp. |
lead_source_id | string or null | For a Meta Page: the lead source its leads go through, where its workflow, consent mode and labels are set (/v1/inbound-sources/{id}). Null for the rest. |
parent_id | string or null | The agency connection this location was connected through, if any. |
polling | object or null | For CRMs bubbl3 checks for changes instead of receiving webhooks (Salesforce): the last check. Null for the rest. |
polling.last_changes | integer | New or changed records the last check found. From 0 to 9007199254740991. |
polling.last_error | string or null | |
polling.last_polled_at | string (date-time) or null | ISO 8601 timestamp. |
provider | string | Provider key, e.g. gohighlevel. |
scopes | string[] | |
status | enum | One of: connected, needs_attention, disconnected. |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Disconnect an integration
DELETE /v1/integrations/connections/:id
Revokes the tokens at the provider (unless another connection, in any workspace, uses the same provider account), deletes them, cancels its sync runs, and with remove_imported_contacts=true deletes the contacts it imported (contacts at full access). An inbox channel's account is turned off in the CRM first, best effort.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
remove_imported_contacts | enum | No | Also delete the contacts this connection imported (needs contacts at full access). One of: true, false. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
disconnected | enum | One of: true. |
id | string | Integration connection id (int_...). |
removed_contacts | integer | From 0 to 9007199254740991. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Import contacts from the provider
POST /v1/integrations/connections/:id/backfill
Starts a resumable import of the contacts matching the filter (needs contacts at full access). Progress is in the sync runs.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
filter | object | No | Default {}. |
filter.list | string | No | Up to 200 characters. |
filter.object | enum | No | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
filter.owner | string | No | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
filter.pipeline | string | No | Up to 200 characters. |
filter.since | string (date-time) | No | ISO 8601 timestamp. |
filter.stage | string | No | Up to 200 characters. |
filter.tag | string | No | Up to 200 characters. |
Response 202
| Field | Type | Description |
|---|---|---|
counts | object | |
counts.created | integer | From -9007199254740991 to 9007199254740991. |
counts.failed | integer | From -9007199254740991 to 9007199254740991. |
counts.merged | integer | From -9007199254740991 to 9007199254740991. |
counts.seen | integer | From -9007199254740991 to 9007199254740991. |
counts.skipped | integer | From -9007199254740991 to 9007199254740991. |
created_at | string (date-time) | ISO 8601 timestamp. |
error | string or null | |
filter | object | |
filter.list | string | Up to 200 characters. |
filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
filter.pipeline | string | Up to 200 characters. |
filter.since | string (date-time) | ISO 8601 timestamp. |
filter.stage | string | Up to 200 characters. |
filter.tag | string | Up to 200 characters. |
finished_at | string (date-time) or null | ISO 8601 timestamp. |
id | string (uuid) | |
kind | enum | One of: backfill, incremental, test. |
started_at | string (date-time) or null | ISO 8601 timestamp. |
status | enum | One of: queued, running, succeeded, failed, cancelled. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Make bubbl3 the texting provider
PUT /v1/integrations/connections/:id/conversation-provider
For a location connection whose provider supports it (GoHighLevel, HubSpot, and the Intercom and Zendesk channels): messages sent from the CRM's or help desk's conversations go out from this line or pool, through bubbl3's normal send checks, and replies and statuses go back to the CRM. Needs conversations at full access. Turning it off stops new sends; the CRM's SMS provider setting is changed in the CRM. HubSpot also needs inbox_id: bubbl3 connects a channel account for this line or pool to that inbox. When HubSpot refuses the channel (the account's plan, or the permissions granted at connect), the answer is still 200, saved as off with eligibility not_eligible and the reason, and texts keep being logged on the contact.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
enabled | boolean | Yes | |
inbox_id | string | No | HubSpot: the inbox to connect bubbl3’s channel to (required to turn it on). Up to 200 characters. |
line_id | string | No | Send from this line. |
pool_id | string | No | Or from this pool. |
Response 200
| Field | Type | Description |
|---|---|---|
account_type | enum | agency: an agency-level install whose locations are connected one by one. One of: agency, location. |
consent_attested_at | string (date-time) or null | When the consent attestation was confirmed. Null if made before it was asked. |
consent_attested_by | string or null | Who confirmed it: user:<id> for a member, api_key:<id> for an API key. |
consent_field | string or null | |
consent_mode | enum | One of: crm_field, web_form, existing_relationship, not_sure. |
conversation_provider | object or null | bubbl3 as the texting provider for this CRM account, if it was ever set up. |
conversation_provider.eligibility | enum | Inbox channels (HubSpot): not_eligible when the CRM refused the channel for this account; bubbl3 then logs texts on the contact instead. One of: unknown, eligible, not_eligible. |
conversation_provider.eligibility_reason | string or null | Why the CRM refused the channel. |
conversation_provider.enabled | boolean | |
conversation_provider.inbox_id | string or null | Inbox channels (HubSpot): the CRM inbox bubbl3’s channel is connected to. |
conversation_provider.line_id | string or null | Line id (ln_...). |
conversation_provider.pool_id | string or null | Pool id (pool_...). |
conversation_provider.updated_at | string (date-time) | ISO 8601 timestamp. |
created_at | string (date-time) | ISO 8601 timestamp. |
external_account_id | string | |
external_account_name | string or null | |
form_ids | string[] or null | For a Meta Page: the lead forms whose leads come in; empty for every form. Null for the rest. |
id | string | Integration connection id (int_...). |
import_filter | object | |
import_filter.list | string | Up to 200 characters. |
import_filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
import_filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
import_filter.pipeline | string | Up to 200 characters. |
import_filter.since | string (date-time) | ISO 8601 timestamp. |
import_filter.stage | string | Up to 200 characters. |
import_filter.tag | string | Up to 200 characters. |
last_error | string or null | |
last_sync_at | string (date-time) or null | ISO 8601 timestamp. |
lead_source_id | string or null | For a Meta Page: the lead source its leads go through, where its workflow, consent mode and labels are set (/v1/inbound-sources/{id}). Null for the rest. |
parent_id | string or null | The agency connection this location was connected through, if any. |
polling | object or null | For CRMs bubbl3 checks for changes instead of receiving webhooks (Salesforce): the last check. Null for the rest. |
polling.last_changes | integer | New or changed records the last check found. From 0 to 9007199254740991. |
polling.last_error | string or null | |
polling.last_polled_at | string (date-time) or null | ISO 8601 timestamp. |
provider | string | Provider key, e.g. gohighlevel. |
scopes | string[] | |
status | enum | One of: connected, needs_attention, disconnected. |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
A clinic connection's data rule and webhook
GET /v1/integrations/connections/:id/healthcare
For NexHealth, Healthie, Mindbody, Boulevard, Vagaro, Zenoti and Housecall Pro connections: only name, phone, email, consent and appointment time come in, plus, for the healthcare ones, any extra field bubbl3 staff added under the workspace’s HIPAA add-on. For Vagaro, Zenoti and Housecall Pro, whose webhooks are set up in the provider, callers with full access get the connection’s webhook address.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
extra_fields | string[] | Extra fields bubbl3 staff added on purpose under the add-on, kept on contacts as fields.phi_<name>; they come in only while the add-on is on. |
hipaa_addon | boolean | Whether the workspace has the HIPAA add-on (set by bubbl3 staff). |
minimum_fields | string[] | The fields that come in: name, phone, email, consent and appointment time. |
provider | string | Provider key, e.g. gohighlevel. |
rule | enum | minimum_fields: a healthcare provider, cut to the minimum by bubbl3 (PRD 9.8). provider_minimum: a provider outside healthcare whose connector reads only the minimum anyway (Vagaro, Housecall Pro). One of: minimum_fields, provider_minimum. |
webhook | object | |
webhook.setup | enum | registered: bubbl3 set it up in the provider. manual: paste url into the provider. partner: bubbl3’s own subscription covers it. pending: not set up yet. One of: registered, manual, partner, pending. |
webhook.url | string (uri) or null | For manual setup, and only for callers with full access: the connection’s own webhook address. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List a connection's inboxes
GET /v1/integrations/connections/:id/inboxes
For a CRM whose texting runs through an inbox channel (HubSpot): the inboxes bubbl3's texts can go to. Asks the provider now. When the CRM account doesn't offer the channel (its plan, or the permissions granted at connect), eligible is false with the reason, and texts keep being logged on the contact. Needs conversations at full access.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].id | string | The CRM's inbox id. |
data[].name | string | |
eligible | boolean | False when the CRM refused access to its inboxes for this account. |
reason | string or null |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List a Meta Page's lead forms
GET /v1/integrations/connections/:id/lead-forms
The Page’s lead forms, and which of them send their leads to bubbl3 (every form when none is chosen). Asks Meta now.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
all_forms | boolean | True when no form is chosen, so every form’s leads come in. |
data | object[] | |
data[].id | string | Meta's form id. |
data[].name | string or null | |
data[].selected | boolean | Whether its leads come in (every form does when none is chosen). |
data[].status | string or null | Meta's form status, such as ACTIVE or ARCHIVED. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Choose a Meta Page's lead forms
PUT /v1/integrations/connections/:id/lead-forms
Only leads from these forms come in; an empty list takes every form. Leads already received stay.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
form_ids | string[] | Yes | The forms whose leads come in. Empty for every form. Up to 200 items. |
Response 200
| Field | Type | Description |
|---|---|---|
account_type | enum | agency: an agency-level install whose locations are connected one by one. One of: agency, location. |
consent_attested_at | string (date-time) or null | When the consent attestation was confirmed. Null if made before it was asked. |
consent_attested_by | string or null | Who confirmed it: user:<id> for a member, api_key:<id> for an API key. |
consent_field | string or null | |
consent_mode | enum | One of: crm_field, web_form, existing_relationship, not_sure. |
conversation_provider | object or null | bubbl3 as the texting provider for this CRM account, if it was ever set up. |
conversation_provider.eligibility | enum | Inbox channels (HubSpot): not_eligible when the CRM refused the channel for this account; bubbl3 then logs texts on the contact instead. One of: unknown, eligible, not_eligible. |
conversation_provider.eligibility_reason | string or null | Why the CRM refused the channel. |
conversation_provider.enabled | boolean | |
conversation_provider.inbox_id | string or null | Inbox channels (HubSpot): the CRM inbox bubbl3’s channel is connected to. |
conversation_provider.line_id | string or null | Line id (ln_...). |
conversation_provider.pool_id | string or null | Pool id (pool_...). |
conversation_provider.updated_at | string (date-time) | ISO 8601 timestamp. |
created_at | string (date-time) | ISO 8601 timestamp. |
external_account_id | string | |
external_account_name | string or null | |
form_ids | string[] or null | For a Meta Page: the lead forms whose leads come in; empty for every form. Null for the rest. |
id | string | Integration connection id (int_...). |
import_filter | object | |
import_filter.list | string | Up to 200 characters. |
import_filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
import_filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
import_filter.pipeline | string | Up to 200 characters. |
import_filter.since | string (date-time) | ISO 8601 timestamp. |
import_filter.stage | string | Up to 200 characters. |
import_filter.tag | string | Up to 200 characters. |
last_error | string or null | |
last_sync_at | string (date-time) or null | ISO 8601 timestamp. |
lead_source_id | string or null | For a Meta Page: the lead source its leads go through, where its workflow, consent mode and labels are set (/v1/inbound-sources/{id}). Null for the rest. |
parent_id | string or null | The agency connection this location was connected through, if any. |
polling | object or null | For CRMs bubbl3 checks for changes instead of receiving webhooks (Salesforce): the last check. Null for the rest. |
polling.last_changes | integer | New or changed records the last check found. From 0 to 9007199254740991. |
polling.last_error | string or null | |
polling.last_polled_at | string (date-time) or null | ISO 8601 timestamp. |
provider | string | Provider key, e.g. gohighlevel. |
scopes | string[] | |
status | enum | One of: connected, needs_attention, disconnected. |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Get a connection's field mappings
GET /v1/integrations/connections/:id/mappings
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].direction | enum | One of: import, writeback, both. Default "import". |
data[].external_field | string | Up to 200 characters. |
data[].local_field | string | |
data[].transform | enum | One of: none, trim, lowercase. Default "none". |
defaults | object[] | |
defaults[].direction | enum | One of: import, writeback, both. Default "import". |
defaults[].external_field | string | Up to 200 characters. |
defaults[].local_field | string | |
defaults[].transform | enum | One of: none, trim, lowercase. Default "none". |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Replace a connection's field mappings
PUT /v1/integrations/connections/:id/mappings
Overrides the defaults per provider field. Applies to the next import.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
mappings | object[] | Yes | Up to 200 items. |
mappings[].direction | enum | No | One of: import, writeback, both. Default "import". |
mappings[].external_field | string | Yes | Up to 200 characters. |
mappings[].local_field | string | Yes | |
mappings[].transform | enum | No | One of: none, trim, lowercase. Default "none". |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].direction | enum | One of: import, writeback, both. Default "import". |
data[].external_field | string | Up to 200 characters. |
data[].local_field | string | |
data[].transform | enum | One of: none, trim, lowercase. Default "none". |
defaults | object[] | |
defaults[].direction | enum | One of: import, writeback, both. Default "import". |
defaults[].external_field | string | Up to 200 characters. |
defaults[].local_field | string | |
defaults[].transform | enum | One of: none, trim, lowercase. Default "none". |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Count the contacts a filter would import
POST /v1/integrations/connections/:id/preview
Asks the provider now. Nothing is imported.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
filter | object | No | Default {}. |
filter.list | string | No | Up to 200 characters. |
filter.object | enum | No | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
filter.owner | string | No | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
filter.pipeline | string | No | Up to 200 characters. |
filter.since | string (date-time) | No | ISO 8601 timestamp. |
filter.stage | string | No | Up to 200 characters. |
filter.tag | string | No | Up to 200 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
at_least | boolean | True when the provider has no total and counting stopped at count (Pipedrive): at least this many match. |
count | integer | Contacts the filter matches in the provider now. From 0 to 9007199254740991. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List an agency connection's locations
GET /v1/integrations/connections/:id/sub-accounts
For an agency-level install (GoHighLevel): the locations the app is installed on, and which are connected in this workspace. Asks the provider now.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].connection_id | string or null | The live connection for this location in this workspace, if connected. |
data[].id | string | The provider's location id. |
data[].name | string or null |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Connect a location of an agency connection
POST /v1/integrations/connections/:id/sub-accounts
Uses the agency's tokens to get the location's own, and creates (or reconnects) that location's connection in this workspace. Consent starts at not_sure. The location records a copy of the agency's consent attestation; an agency connected before attestations were asked must reconnect first (400).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
sub_account_id | string | Yes | The provider's location id. Up to 200 characters. |
Response 201
| Field | Type | Description |
|---|---|---|
account_type | enum | agency: an agency-level install whose locations are connected one by one. One of: agency, location. |
consent_attested_at | string (date-time) or null | When the consent attestation was confirmed. Null if made before it was asked. |
consent_attested_by | string or null | Who confirmed it: user:<id> for a member, api_key:<id> for an API key. |
consent_field | string or null | |
consent_mode | enum | One of: crm_field, web_form, existing_relationship, not_sure. |
conversation_provider | object or null | bubbl3 as the texting provider for this CRM account, if it was ever set up. |
conversation_provider.eligibility | enum | Inbox channels (HubSpot): not_eligible when the CRM refused the channel for this account; bubbl3 then logs texts on the contact instead. One of: unknown, eligible, not_eligible. |
conversation_provider.eligibility_reason | string or null | Why the CRM refused the channel. |
conversation_provider.enabled | boolean | |
conversation_provider.inbox_id | string or null | Inbox channels (HubSpot): the CRM inbox bubbl3’s channel is connected to. |
conversation_provider.line_id | string or null | Line id (ln_...). |
conversation_provider.pool_id | string or null | Pool id (pool_...). |
conversation_provider.updated_at | string (date-time) | ISO 8601 timestamp. |
created_at | string (date-time) | ISO 8601 timestamp. |
external_account_id | string | |
external_account_name | string or null | |
form_ids | string[] or null | For a Meta Page: the lead forms whose leads come in; empty for every form. Null for the rest. |
id | string | Integration connection id (int_...). |
import_filter | object | |
import_filter.list | string | Up to 200 characters. |
import_filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
import_filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
import_filter.pipeline | string | Up to 200 characters. |
import_filter.since | string (date-time) | ISO 8601 timestamp. |
import_filter.stage | string | Up to 200 characters. |
import_filter.tag | string | Up to 200 characters. |
last_error | string or null | |
last_sync_at | string (date-time) or null | ISO 8601 timestamp. |
lead_source_id | string or null | For a Meta Page: the lead source its leads go through, where its workflow, consent mode and labels are set (/v1/inbound-sources/{id}). Null for the rest. |
parent_id | string or null | The agency connection this location was connected through, if any. |
polling | object or null | For CRMs bubbl3 checks for changes instead of receiving webhooks (Salesforce): the last check. Null for the rest. |
polling.last_changes | integer | New or changed records the last check found. From 0 to 9007199254740991. |
polling.last_error | string or null | |
polling.last_polled_at | string (date-time) or null | ISO 8601 timestamp. |
provider | string | Provider key, e.g. gohighlevel. |
scopes | string[] | |
status | enum | One of: connected, needs_attention, disconnected. |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List a connection's sync runs
GET /v1/integrations/connections/:id/sync-runs
The 50 most recent imports, newest first.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].counts | object | |
data[].counts.created | integer | From -9007199254740991 to 9007199254740991. |
data[].counts.failed | integer | From -9007199254740991 to 9007199254740991. |
data[].counts.merged | integer | From -9007199254740991 to 9007199254740991. |
data[].counts.seen | integer | From -9007199254740991 to 9007199254740991. |
data[].counts.skipped | integer | From -9007199254740991 to 9007199254740991. |
data[].created_at | string (date-time) | ISO 8601 timestamp. |
data[].error | string or null | |
data[].filter | object | |
data[].filter.list | string | Up to 200 characters. |
data[].filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
data[].filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
data[].filter.pipeline | string | Up to 200 characters. |
data[].filter.since | string (date-time) | ISO 8601 timestamp. |
data[].filter.stage | string | Up to 200 characters. |
data[].filter.tag | string | Up to 200 characters. |
data[].finished_at | string (date-time) or null | ISO 8601 timestamp. |
data[].id | string (uuid) | |
data[].kind | enum | One of: backfill, incremental, test. |
data[].started_at | string (date-time) or null | ISO 8601 timestamp. |
data[].status | enum | One of: queued, running, succeeded, failed, cancelled. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Test an integration connection
POST /v1/integrations/connections/:id/test
Makes one read call to the provider with the stored tokens.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Integration connection id (int_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
account_name | string or null | |
error | string or null | |
ok | boolean |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Start connecting an integration
GET /v1/integrations/:provider/authorize
Returns the provider's consent page. After consent the provider redirects to the callback, which hands the code to the dashboard's connect page; that page completes the connection for the signed-in user. Providers whose consent page is on the customer's own site (Shopify) need account, the store's myshopify.com address; anything that isn't one is a 400.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | Provider key, e.g. gohighlevel. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
account | string | No | For providers with authorize_account in the catalog (Shopify): the store the consent page is on, like acme.myshopify.com. Ignored by other providers. Up to 200 characters. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
url | string (uri) | The provider's consent page. Open it in the browser. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
OAuth callback
GET /v1/integrations/:provider/callback
Providers redirect here after consent. Nothing is exchanged here: a well-formed, signed, unexpired state is passed with the code to the dashboard's connect page in the URL fragment, and the signed-in user completes the connection there. Anything else redirects to the same error page.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | Provider key, e.g. gohighlevel. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
state | string | No | Up to 4096 characters. |
code | string | No | Up to 4096 characters. |
auth_code | string | No | Up to 4096 characters. |
error | string | No | Up to 512 characters. |
location | string | No | Up to 16 characters. |
accounts-server | string | No | Up to 200 characters. |
shop | string | No | Up to 200 characters. |
hmac | string | No | Up to 200 characters. |
Errors: 302. See errors for the shape and codes.
Provider uninstall callback
DELETE /v1/integrations/:provider/callback
Pipedrive calls the app's callback URL with DELETE when a user uninstalls bubbl3, authenticated with the app's own client id and secret. bubbl3 disconnects that user's connection (contacts stay). Every rejection is the same 403; a verified callback already stored is answered with received: 0.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | Provider key, e.g. gohighlevel. |
Response 200
| Field | Type | Description |
|---|---|---|
received | integer | From 0 to 9007199254740991. |
Errors: 403, 429. See errors for the shape and codes.
Finish connecting an integration
POST /v1/integrations/:provider/complete
Exchanges the provider's code for the signed-in user who started the connection, in the same workspace. The state is single use. Any state that is invalid, expired, used, for another provider, or from another user or workspace gets the same 400. consent_attested: true is required (400 without it): the connection records who confirmed that everyone the business sends has agreed to receive texts, and when, and the confirmation is audited.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | Provider key, e.g. gohighlevel. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
account_type | enum | No | For providers with agency installs (GoHighLevel): whether the code is for the agency or one location. One of: agency, location. |
code | string | Yes | Up to 4096 characters. |
consent_attested | enum | Yes | Required: confirms "Everyone we send to bubbl3 has agreed to receive texts from us." bubbl3 records who confirmed it and when. One of: true. |
region | string | No | For providers with data centres (Zoho) or stores (Shopify): the region or store the callback's fragment named (oauth_region). |
state | string | Yes | Up to 4096 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
account_type | enum | agency: an agency-level install whose locations are connected one by one. One of: agency, location. |
consent_attested_at | string (date-time) or null | When the consent attestation was confirmed. Null if made before it was asked. |
consent_attested_by | string or null | Who confirmed it: user:<id> for a member, api_key:<id> for an API key. |
consent_field | string or null | |
consent_mode | enum | One of: crm_field, web_form, existing_relationship, not_sure. |
conversation_provider | object or null | bubbl3 as the texting provider for this CRM account, if it was ever set up. |
conversation_provider.eligibility | enum | Inbox channels (HubSpot): not_eligible when the CRM refused the channel for this account; bubbl3 then logs texts on the contact instead. One of: unknown, eligible, not_eligible. |
conversation_provider.eligibility_reason | string or null | Why the CRM refused the channel. |
conversation_provider.enabled | boolean | |
conversation_provider.inbox_id | string or null | Inbox channels (HubSpot): the CRM inbox bubbl3’s channel is connected to. |
conversation_provider.line_id | string or null | Line id (ln_...). |
conversation_provider.pool_id | string or null | Pool id (pool_...). |
conversation_provider.updated_at | string (date-time) | ISO 8601 timestamp. |
created_at | string (date-time) | ISO 8601 timestamp. |
external_account_id | string | |
external_account_name | string or null | |
form_ids | string[] or null | For a Meta Page: the lead forms whose leads come in; empty for every form. Null for the rest. |
id | string | Integration connection id (int_...). |
import_filter | object | |
import_filter.list | string | Up to 200 characters. |
import_filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
import_filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
import_filter.pipeline | string | Up to 200 characters. |
import_filter.since | string (date-time) | ISO 8601 timestamp. |
import_filter.stage | string | Up to 200 characters. |
import_filter.tag | string | Up to 200 characters. |
last_error | string or null | |
last_sync_at | string (date-time) or null | ISO 8601 timestamp. |
lead_source_id | string or null | For a Meta Page: the lead source its leads go through, where its workflow, consent mode and labels are set (/v1/inbound-sources/{id}). Null for the rest. |
parent_id | string or null | The agency connection this location was connected through, if any. |
polling | object or null | For CRMs bubbl3 checks for changes instead of receiving webhooks (Salesforce): the last check. Null for the rest. |
polling.last_changes | integer | New or changed records the last check found. From 0 to 9007199254740991. |
polling.last_error | string or null | |
polling.last_polled_at | string (date-time) or null | ISO 8601 timestamp. |
provider | string | Provider key, e.g. gohighlevel. |
scopes | string[] | |
status | enum | One of: connected, needs_attention, disconnected. |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Connect an integration with an API key
POST /v1/integrations/:provider/connect
For providers the customer connects with their own API key (ActiveCampaign, Copper, Freshsales, Lofty; the catalog's key_fields says what each needs). bubbl3 checks the credentials with one read call to the provider, then makes the connection (or reconnects the account's live one) and keeps the key sealed like an OAuth token. Credentials the provider refuses are a 400 with the reason, and nothing is stored. consent_attested: true is required (400 without it) and recorded with who and when, as for a one-click connection. The key is never returned. Limited to 10 attempts a minute per workspace (bursts of 5); past that a 429 with Retry-After, and the provider isn't called. A provider whose connect checks a staff login (Mindbody) also allows 5 failed checks an hour per account, whichever workspace tries; past that a 429 with Retry-After too.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | Provider key, e.g. gohighlevel. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
account_id | string | No | The account bubbl3 connects to at the provider: NexHealth's location id, Mindbody's site id, Boulevard's business id, Vagaro's business id, Zenoti's center id. Up to 100 characters. |
account_url | string | No | ActiveCampaign: the account's API URL (https://youraccount.api-us1.com). Up to 300 characters. |
api_key | string | No | The API key from the provider. Up to 512 characters. |
api_secret | string | No | The secret that goes with the key (Boulevard's API secret, Vagaro's client secret). Up to 512 characters. |
consent_attested | enum | Yes | Required: confirms "Everyone we send to bubbl3 has agreed to receive texts from us." bubbl3 records who confirmed it and when. One of: true. |
domain | string | No | Freshsales: the account's bundle domain (yourcompany.myfreshworks.com). Up to 300 characters. |
password | string | No | Mindbody: that staff login’s password, used once for the check. Never stored. Up to 200 characters. |
user_email | string (email) | No | Copper: the email of the Copper user the key belongs to. Up to 254 characters. |
username | string | No | Mindbody: a staff login for the site, checked once to confirm the site is the customer's. Never stored. Up to 200 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
account_type | enum | agency: an agency-level install whose locations are connected one by one. One of: agency, location. |
consent_attested_at | string (date-time) or null | When the consent attestation was confirmed. Null if made before it was asked. |
consent_attested_by | string or null | Who confirmed it: user:<id> for a member, api_key:<id> for an API key. |
consent_field | string or null | |
consent_mode | enum | One of: crm_field, web_form, existing_relationship, not_sure. |
conversation_provider | object or null | bubbl3 as the texting provider for this CRM account, if it was ever set up. |
conversation_provider.eligibility | enum | Inbox channels (HubSpot): not_eligible when the CRM refused the channel for this account; bubbl3 then logs texts on the contact instead. One of: unknown, eligible, not_eligible. |
conversation_provider.eligibility_reason | string or null | Why the CRM refused the channel. |
conversation_provider.enabled | boolean | |
conversation_provider.inbox_id | string or null | Inbox channels (HubSpot): the CRM inbox bubbl3’s channel is connected to. |
conversation_provider.line_id | string or null | Line id (ln_...). |
conversation_provider.pool_id | string or null | Pool id (pool_...). |
conversation_provider.updated_at | string (date-time) | ISO 8601 timestamp. |
created_at | string (date-time) | ISO 8601 timestamp. |
external_account_id | string | |
external_account_name | string or null | |
form_ids | string[] or null | For a Meta Page: the lead forms whose leads come in; empty for every form. Null for the rest. |
id | string | Integration connection id (int_...). |
import_filter | object | |
import_filter.list | string | Up to 200 characters. |
import_filter.object | enum | Salesforce: import only Leads or only Contacts (both when left out). One of: lead, contact. |
import_filter.owner | string | The CRM owner's id (HubSpot's hubspot_owner_id). Up to 200 characters. |
import_filter.pipeline | string | Up to 200 characters. |
import_filter.since | string (date-time) | ISO 8601 timestamp. |
import_filter.stage | string | Up to 200 characters. |
import_filter.tag | string | Up to 200 characters. |
last_error | string or null | |
last_sync_at | string (date-time) or null | ISO 8601 timestamp. |
lead_source_id | string or null | For a Meta Page: the lead source its leads go through, where its workflow, consent mode and labels are set (/v1/inbound-sources/{id}). Null for the rest. |
parent_id | string or null | The agency connection this location was connected through, if any. |
polling | object or null | For CRMs bubbl3 checks for changes instead of receiving webhooks (Salesforce): the last check. Null for the rest. |
polling.last_changes | integer | New or changed records the last check found. From 0 to 9007199254740991. |
polling.last_error | string or null | |
polling.last_polled_at | string (date-time) or null | ISO 8601 timestamp. |
provider | string | Provider key, e.g. gohighlevel. |
scopes | string[] | |
status | enum | One of: connected, needs_attention, disconnected. |
updated_at | string (date-time) | ISO 8601 timestamp. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.