Boom Ai · AsyncAPI Specification
Boom Ai Webhooks
Version
View Spec
View on GitHub
CompanyArtificial IntelligenceConversational AICustomer EngagementCustomer Data PlatformMessagingWhatsAppSMSMarketing AutomationE-CommerceAgentsMCPAsyncAPIWebhooksEvents
AsyncAPI Specification
generated: '2026-08-13'
method: searched
source: https://docs.useboom.ai/webhooks
spec_type: none
asyncapi_published: false
asyncapi_note: >-
Boom publishes NO AsyncAPI document — probed the docs host and the BOOM-TML GitHub org.
The webhook surface below is captured from the provider's own prose reference and is
recorded as a Webhooks catalog, not as a machine-readable event contract. Nothing here
is invented; payload field lists are the ones Boom prints.
surface:
direction: outbound
protocol: HTTPS POST
content_type: application/json
enablement: per-workspace, off by default (Settings -> Webhooks; requires Settings -> HTTP Credentials)
configuration: UI only — subscriptions are created in the Boom app, not over the API
related_api: GET /api/v1/http-credentials (http_credentials_list) lists the credentials a subscription can use
timeout_seconds: 10
envelope:
fields:
- {name: id, description: 'Event id (e.g. evt_cm7x…); also sent as the Idempotency-Key request header'}
- {name: type, description: The event type, or "ping" for the synthetic test delivery}
- {name: occurredAt, description: ISO 8601 timestamp}
- {name: organizationId, description: The Boom organization the event belongs to}
- {name: data, description: Event-specific payload}
idempotency_header: Idempotency-Key
events:
- name: journey_run.started
fires_when: Someone was enrolled and their run began — at enrollment, BEFORE the first message is sent. Not a delivery receipt.
payload_keys: [run, trigger, startedAt]
run_fields: [engagementId, initiativeId, initiativeName, workflowId, customerId, personId, personExternalId]
trigger_kinds:
- {kind: cdp_event, extra: [eventName, eventId]}
- {kind: segment, extra: [segmentId]}
- {kind: manual, extra: []}
gotcha: >-
personId is frequently null — populated only on the CDP-event enrollment path.
Join on personExternalId (your own id) instead.
- name: journey_run.ended
fires_when: The run reached a terminal state, however it ended. May be days after started; durationMs gives the real gap.
payload_keys: [run, outcome]
outcome_fields: [status, reason, lastSignal, terminalNode, error, startedAt, endedAt, durationMs, messagesSent, messagesReceived]
reasons: [completed, no_reply, abandoned, failed_node_error, failed_engine, canceled_operator,
canceled_initiative, canceled_participant_stop, expired]
signals: [REPLIED, CLOSED, TIMEOUT, STALE, null]
gotcha: >-
Branch on reason, not status — three materially different endings all land on
status CONVERSATION_COMPLETE. `expired` is reserved and cannot currently occur.
outcome.error is an object ({errorName}) or null, never a message or stack.
- name: enrollment.rejected
fires_when: A CDP event matched a journey trigger but no run started. CDP-event path only — segment, manual, CSV and API enrollment never emit it.
payload_keys: [reason, detail, initiativeId, workflowId, eventName, eventId, personId, personExternalId, customerId]
reasons:
- {reason: no_channel, means: No reachable phone or email for this person}
- {reason: active_run, means: Already in a live run of this journey, detail: existingEngagementId}
- {reason: frequency_cap, means: Hit the initiative's enrollment cap, detail: 'count, window'}
- {reason: no_workflow, means: The journey stopped being published mid-flight}
- {reason: internal_error, means: Enrollment failed after retries, detail: errorName}
gotcha: '"No trigger matched" does not emit. Treat initiativeId and workflowId as nullable.'
- name: ping
fires_when: Someone clicks the test-delivery button. Nothing subscribes to it.
payload_keys: [id, type, occurredAt, organizationId, data]
gotcha: Handle as a no-op (return 2xx and ignore) so a colleague's test never reads as a real run.
security:
authentication: >-
A credential is REQUIRED and must actually authenticate — BEARER, API_KEY (header or
query parameter) or BASIC. A "No authentication" credential cannot be attached: it is
greyed out in the picker, rejected on save, and refused at delivery rather than sent
unsigned.
signature: none — authenticity is proven by the credential Boom sends, not by a payload signature
url_requirements: >-
Must start with a literal https:// (plain http rejected on save). Private and loopback
addresses save but are blocked at delivery.
per_environment: >-
A subscription URL may reference {{env.KEY}}, and credential keys may have a global row
plus per-environment overrides. A key with no row for an environment and no global row
causes deliveries to be DROPPED, not sent unauthenticated.
delivery:
guarantee: at-least-once delivery, at-most-once emission
dedupe_on: id
retries:
- {response: 2xx, behavior: delivered}
- {response: '5xx, 408, 429', behavior: retried up to 3 times — 4 attempts total}
- {response: no response (timeout, DNS, connection reset), behavior: retried up to 3 times}
- {response: any other 4xx, behavior: permanent — not retried (includes 401 and 403)}
reconciliation_warning: >-
Boom states plainly that webhooks are NOT a source of truth: if emission fails the run
is permanently unreported and no retry recovers it, and a subscription with an
unresolvable credential or {{env.*}} token drops the event outright. Consumers must
reconcile periodically rather than treat the stream as a ledger.
head_of_line_warning: >-
Deliveries for one event are attempted in sequence; a retryable failure on one
subscription interrupts the pass and can starve the subscriptions after it.
x-evidence:
- {url: 'https://docs.useboom.ai/webhooks.md', status: 200, checked: '2026-08-13'}