Connect Kustomer
Bring Kustomer conversations, messages, and customer records into Fibric as governed events, and let operators write notes and status changes back idempotently. This guide covers creating a role-scoped API key, installing the cn-kustomer connector, granting capabilities, verifying that events flow, and diagnosing the failures you are most likely to hit.
The cn-kustomer connector runs in production today under BearScope, Fibric's flagship product, on live specialty-commerce conversations. It senses conversations and messages as they arrive and change, customer records with order and contact history, and SLA state, satisfaction scores, and reopen events. Acting, it writes notes to a conversation, updates status and assignment, and syncs call status from your voice platform onto the customer timeline. Every write is idempotent: a retried note is a safe no-op, never a duplicate. See Connectors for the general model.
Prerequisites
| Requirement | Why |
|---|---|
| A Kustomer instance with admin access | Creating API keys requires a role that can reach Settings → Security → API Keys. |
| A Kustomer API key with conversation read and note write scopes | The minimum the connector needs to sense and act. Step 1 walks through creating it. |
| The Fibric CLI, authenticated | fibric auth login and fibric auth whoami confirm your workspace. See Installation and the CLI reference. |
| A Fibric workspace on the free plan or later | The platform is free during early access; premium connectors are priced from $29 per source per month. |
Create a role-scoped API key in Kustomer
In Kustomer, go to Settings → Security → API Keys and create a new key. Kustomer keys carry roles, and each role expands to a set of org permissions. Do not use an admin key: create a key whose roles grant exactly the permissions below and nothing more. The connector fails closed on anything it was not granted, so an over-scoped key buys no capability, only risk.
Required permissions
| Permission | Access | Used for |
|---|---|---|
org.permission.conversation | read | Sensing conversations as they arrive and change, including SLA state and reopen history. |
org.permission.message | read | Sensing individual messages within a conversation. |
org.permission.customer | read | Customer records with order and contact history. |
org.permission.note | write | Writing internal notes to a conversation, idempotently. |
org.permission.conversation | write | Optional. Only needed if you grant status or assignment updates in step 3. |
Name the key so its purpose is obvious in an audit six months from now, for example fibric-connector-prod. Copy the key once at creation; Kustomer does not show it again.
If you plan to start read-only, create the key without org.permission.note write and add it later when you enable writes. Fibric's trust layer blocks ungranted actions regardless, but a key that cannot write is a second, independent wall. See Governance & trust.
Install the connector
Add cn-kustomer from the marketplace and bind it to the support role. Operators ask for support capabilities such as conversation.note.write, never for Kustomer by name, so a later move to another support platform is a rebinding, not a rewrite. The CLI walks the handshake the connector's auth declares: an API key prompt, because the connector is defined with auth: apiKey(). The key goes directly into your tenant's secret store; the CLI never writes it to disk.
# find the connector, then install it bound to the support role
fibric connectors search kustomer
fibric connectors add cn-kustomer --as support \
--connection kustomer-prod \
--config '{"subdomain":"acme"}'
Configuration parameters
Non-secret configuration is passed with --config and lands in the connector's ctx.config. Credentials never go here.
| Parameter | Type | Description |
|---|---|---|
subdomain | string | Required. Your Kustomer subdomain: the acme in acme.kustomerapp.com. |
poll_interval | string | Optional, default 60s. Cadence of the poll backfill that runs alongside webhooks. |
backfill_since | ISO 8601 date | Optional. How far back the first sync reads. Unset means webhook-forward only, no history. |
Grant capabilities
Installing a connector exposes capabilities; it grants nothing. An operator gets exactly the capabilities you list in its manifest, and the deterministic executor blocks anything else by omission. List what the connection now exposes:
fibric capabilities ls
Grant an operator the read capabilities it senses through and only the writes its job needs. A triage analyst that reads conversations and leaves notes needs two capabilities, not five. The Capabilities page covers the indirection in full; Build an ops analyst is a worked example against this connector.
Writes also need a trust policy. Policy is fail-closed: an action with no matching rule is blocked, and you get the blocking rule by omission rather than by writing it. Apply and validate before anything runs live:
# governs writes back into Kustomer. default is deny.
policy: support-writes
rules:
- allow: conversation.note.write
limit:
per: hour
max: 100
single_flight: conversation_id # one write in flight per conversation
- allow: conversation.status.write
limit:
per: hour
max: 25
default: deny
fibric policy apply ./policy.yaml
fibric policy validate support-writes
The 657-message flood, one retry loop writing the same message to a conversation 657 times, is the incident this design answers. Every note write carries an entity_key (the conversation) and an idempotency_key (the specific write), so a replay dedupes with a DEDUP disposition instead of duplicating. See Single-flight & idempotency and Write guardrails that hold.
Verify events are flowing
Send a test message into any Kustomer conversation, then tail the event stream. Each Kustomer change arrives as a tenant-scoped event envelope with source: "kustomer" and a dotted event_type.
fibric events tail --source kustomer
Emitted event types
| Event type | Kind | Fires when |
|---|---|---|
conversation.created | webhook | A new conversation opens on any channel. |
conversation.message.created | webhook | A message lands on a conversation, inbound or outbound. |
conversation.status.changed | webhook | Status moves, including reopens after done. |
conversation.satisfaction.updated | webhook | A CSAT response is recorded. |
conversation.sla.breached | poll | An SLA target passes without the required response. |
customer.updated | poll | A customer record changes, caught by the poll backfill. |
Then confirm the write path with a dry run. Side-effecting tools dry-run by default: input validation and the trust evaluation execute, the handler does not.
fibric connectors test cn-kustomer note.write \
--connection kustomer-prod \
--args '{"conversation_id":"cnv_63k1","body":"connectivity check"}'
Choose webhook or poll delivery
The connector's event streams declare a delivery kind, webhook or poll, in the connector definition. Webhooks are the primary path for conversation and message events: Kustomer pushes changes as they happen, and Fibric verifies and deduplicates each delivery. The poll backfill runs alongside at poll_interval and covers what webhooks structurally miss: changes made while a webhook endpoint was unreachable, resources with no webhook topic, and the initial history read when backfill_since is set.
Both paths feed the same envelope stream, and deduplication keys on the underlying resource change, so a change seen by both paths lands once. You do not choose between them; you tune the poll interval. A shorter interval narrows the worst-case gap for poll-only streams at the cost of more API calls against your Kustomer rate limit. For webhook endpoint mechanics and signature verification, see Receive webhooks reliably.
Common failures
Every failure below is visible in fibric connectors test output or in receipts; the connector's probe reports the first three on install.
| Symptom | Cause | Fix |
|---|---|---|
Probe fails with 401 Unauthorized | The API key is wrong, truncated on paste, or was revoked in Kustomer. | Create a fresh key under Settings → Security → API Keys and re-run fibric connectors add to replace the stored secret. |
Reads work, note.write --live fails with 403 | The key's roles lack org.permission.note write. | Kustomer keys cannot be re-scoped in place. Create a new key with the write permission and reinstall the connection. |
Events arrive in bursts, then 429 in connector logs | The poll interval plus your other Kustomer API consumers exceed the org rate limit. | Raise poll_interval. The connector honors Retry-After and backs off; nothing is lost, only delayed. |
| Message events lag by up to a minute | Webhook delivery is failing and the poll backfill is carrying the stream. | Expected degradation, not data loss. Check webhook health with fibric connectors test cn-kustomer --contract and see Receive webhooks reliably. |
conversation.status.write receipts show BLOCK | No trust rule allows the action; evaluation is default-closed. | Add an allow rule and re-run fibric policy apply. A block here is the system working. See Trust tiers. |
Duplicate-looking receipts marked DEDUP | A retried write hit the idempotency check. | No action needed. DEDUP means the duplicate was caught, not that it ran twice. |
Next steps
- Build an ops analyst: an operator that reads these conversations and reports what it sees.
- Catch order risk early: pair Kustomer with Magento so conversation context meets order state. Connect the store with Connect Magento.
- Write guardrails that hold: the trust policy patterns behind step 3.
- Events API: the same stream, programmatically.
- Tenancy & isolation: how every envelope stays walled inside your tenant.