> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# CDP integration console: mint the ingest secret and wire outbound destinations

> Operate the Source (inbound) and Destinations (outbound) tabs on Integrations → CDP — mint and rotate the per-tenant ingest secret, connect Segment, RudderStack, mParticle, Hightouch, or a generic webhook, and read the circuit-breaker badges before deliveries stall.

# CDP integration console: source and destinations

The **Integrations → CDP** page is the operator console for event flow in both directions. Two of its tabs own the plumbing everything else builds on:

* **Source (inbound)** — mints the per-tenant ingest secret your apps sign events with, and shows the endpoint URL to point them at.
* **Destinations (outbound)** — forwards Orbit events out to your CDP, marketing platform, or any HMAC-verifying webhook receiver: Segment, RudderStack, mParticle, Hightouch, or a generic `webhook` kind.

Both tabs are live configuration — a mistake here stalls inbound eventing or outbound delivery for the whole workspace. This guide walks the full lifecycle on both sides, with a worked Segment destination and a worked webhook destination, the failure states you will actually hit, and the role gating behind every mutation.

## 1. What the page is for

Open **Integrations → CDP**. The page header describes the two directions the console governs: stream events from your app into Orbit (source), and forward Orbit's events out to your CDP or data warehouse (destinations). Two schema-governance shortcuts sit at the top of the page as tiles:

* **Tracking plan** — declare the events your apps send and the expected property shape per event, then review runtime violations captured at ingest. See the [CDP tracking plan guide](/guides/cdp-tracking-plan).
* **Event schemas** — enforce a JSON Schema per event type at ingest, with drop / warn / ignore modes for invalid payloads.

The **Source (inbound)** and **Destinations (outbound)** tabs below are the subject of this guide. The remaining tabs (reverse-ETL sources, catalogs, identity, governance, DLQ, and more) each have their own surfaces; the two here are where event flow starts.

## 2. Source (inbound): mint and rotate the ingest secret

### Mint a secret

The Source tab lists your workspace's ingest secrets with their status (`active`, `rotating`, `revoked`), creation time, and last-used time. Most workspaces hold one active secret; rotate by minting a replacement before revoking the old one.

1. Open **Integrations → CDP → Source (inbound)** and click **Mint secret**.
2. The plaintext secret appears exactly once in a reveal dialog. Copy it into your app's environment or secrets manager now — afterwards only a short prefix is retrievable, so a lost secret is replaced, not recovered.
3. The new row shows `active`. If you are rotating, the old secret keeps verifying until you revoke it, so running apps keep delivering while you redeploy.

### The endpoint URL and required headers

Once a secret is active, the **Endpoint** card at the top of the tab composes your track URL:

```
https://api.orbit.devotel.io/cdp/v1/<ingest_id>/track
```

The `<ingest_id>` is the secret's own id — it routes the request to your workspace and is public-safe (it cannot sign anything by itself). Every request carries three headers:

```
X-Orbit-CDP-Timestamp: <unix_seconds>
X-Orbit-CDP-Nonce: <random_unique_per_request>
X-Orbit-CDP-Signature: v1=<hex hmac sha256>
```

The signature covers `<timestamp>.<nonce>.<raw body>` keyed by the secret plaintext. The full wire contract — including the 5-minute timestamp tolerance and nonce replay rules — is in [Sign CDP ingest requests without a client SDK](/guides/cdp-ingest-signing).

### Where ingested events land

Events accepted at the ingest endpoint then meet your workspace's declared contract. The where-it-lands chain:

* **Tracking plan** (`/integrations/cdp/tracking-plan`) declares which events you expect and what shape their properties take; violations log in soft mode and reject in strict mode.
* **Event schemas** (`/integrations/cdp/schemas`) attach a JSON Schema per event type and choose a policy — drop, warn, or ignore invalid payloads.

Start new producers with the plan in soft mode and a warn-only schema, then tighten as payloads stabilize.

### Rotate and revoke

To rotate safely:

1. **Mint secret** — the new plaintext shows once. Deploy it to the app.
2. Wait for the old row's **Last used** time to stop advancing (or just confirm the redeploy completed).
3. Click **Revoke** on the old row and confirm. Revoking takes effect immediately — any integration still signing with that secret starts failing HMAC verification at once — so the confirm dialog tells you to redeploy the replacement first.

A leaked key follows the same path, compressed: mint, revoke, redeploy.

## 3. Destinations (outbound): subscribe a receiver

### Add a destination

Click **Add destination** on the **Destinations (outbound)** tab. The dialog asks for:

* **Name** — free text (`Segment production`, `Warehouse webhook`).
* **Destination kind** — `Segment`, `RudderStack`, `mParticle`, `Hightouch`, `Marketo`, `Google Analytics 4`, `Amplitude`, plus a long catalog of Nango-routed platforms (HubSpot, Salesforce, Braze, Iterable, Customer.io, Klaviyo, and more), or `Generic webhook` for any HTTPS receiver you control.
* **Target URL (HTTPS)** — the endpoint Orbit delivers signed events to. Plain `http` URLs are rejected in the form; OAuth platforms connected through Nango skip the URL and connect from the platform card grid at the top of the tab.
* **Events** — a fixed catalog of Orbit event types (`contact.created`, `message.delivered`, `conversation.started`, `agent.handoff_occurred`, …) to subscribe to, or **Subscribe to all** to forward everything the workspace emits. Narrow this later from the destination's settings.

On create, a reveal dialog shows the destination's **signing secret** exactly once. Configure your receiver's verifier with it — every delivery is HMAC-signed, same scheme as the [webhook signature verification](/guides/verify-webhook-signatures) guide covers, so the receiver authenticates Orbit before it trusts a payload.

The destinations table lists each subscription with name, target URL, kind, subscribed events, a status badge, and last-activity time. A summary line above the table counts destinations and flags how many are circuit-open.

### Worked example: Segment destination

1. **Add destination** → kind `Segment`, name `Segment production`, target URL `https://api.segment.example.com/orbit-inbound` (your Segment-side intake endpoint), events = pick the catalog list.
2. Copy the revealed signing secret into your Segment-side verifier configuration.
3. Click **Send test event** on the row. Orbit dispatches a real signed test-ping payload synchronously and reports the outcome; the delivery is recorded so it shows alongside live deliveries in the log. (Nango-routed kinds can't use the test button — verify those from the integration's own settings page.)
4. Confirm the row's status badge flips to **Active** and **Last activity** shows a fresh success timestamp.

### Worked example: generic webhook destination

1. Stand up an HTTPS receiver that verifies `X-Orbit-CDP-Signature` against the signing secret (same canonical-string scheme as the ingest side, so a single HMAC helper covers both directions).
2. **Add destination** → kind `Generic webhook`, paste the receiver URL, **Subscribe to all** events.
3. Wire the verifier check: recompute the signature over `<timestamp>.<nonce>.<raw body>` and reject mismatches with 401 before processing.
4. **Send test event** and confirm the receiver logs a verified delivery.

### Per-destination circuit-breaker badge

Each destination row carries one of four health states:

| Badge            | Meaning                                                                                                  |
| ---------------- | -------------------------------------------------------------------------------------------------------- |
| **Active**       | Deliveries are flowing.                                                                                  |
| **Paused**       | Deliveries are held by operator action.                                                                  |
| **Circuit open** | Five consecutive delivery failures tripped the breaker; the destination is excluded from new dispatches. |
| **Disabled**     | The subscription is off.                                                                                 |

The page header surfaces the circuit-open count (**"N circuit-open — auto-reopens on first 2xx"**) so a stalled destination is visible without opening the tab. The breaker doesn't need intervention to recover: the first successful delivery flips the row back to `active` automatically. Once a circuit opens, deliveries stop counting against it until the destination answers 2xx again — manual resets and replays are the two recovery paths below.

### When to use the reset CTA

The **Reset** button appears on circuit-open rows. Use it after you've fixed the destination (restored the endpoint, corrected the URL, or updated the verifier) and want to close the circuit immediately instead of waiting for the auto-recovery path. It hand-flips the status back to `active` so new events dispatch right away; replay a failed backlog from the [DLQ](/guides/cdp-event-debugger-and-dlq) afterwards so nothing is lost.

### Rotate a destination signing secret

Click the key icon on a row. A confirm dialog warns that the fresh plaintext shows once: the dispatcher dual-signs deliveries through a seven-day grace window, so deliveries keep verifying while you update the receiver. Paste the new secret into the receiver's verifier within that window — after it expires, only the new secret verifies. This is the same dual-sign rotation pattern the platform uses for channel webhook endpoints.

### Delete a destination

The trash icon stops all future forwarding to the target. Pending in-flight retries are dropped on delete — anything you still want re-driven, replay from the DLQ first.

## 4. Verify delivery

### Recent event log and retry/backoff behavior

Delivery history lives on the **DLQ** tab of the same page: every failed delivery across all subscriptions, grouped by destination, with the HTTP status or transport error, the attempt count, and the timestamp of the last attempt. Each row has a single-delivery **Retry** action that re-drives exactly that payload through the normal pipeline, and each destination group header has a **Replay failed** action that re-dispatches up to 50 recent failures per run — so restoring from an outage is one click, not fifty. The full walkthrough is in [CDP event debugger and DLQ](/guides/cdp-event-debugger-and-dlq).

The dispatcher retries failing destinations automatically; a delivery only lands in the DLQ once the automatic attempts exhaust. Successes report on the destination row's **Last activity** column, which surfaces the latest success timestamp inline (and the latest failure while the circuit is open), so healthy destinations confirm at a glance without opening the log.

For an SLA-style view per destination — total / success / failed / pending counts, an uptime percentage over a sliding window, and p50 / p95 delivery response times — the API exposes `GET /api/v1/cdp/subscriptions/:id/sla`, which the destination card renders as the "sync uptime" figure.

### Test event before going live

The **Send test event** button on a row dispatches a real signed payload synchronously and reports the outcome, recording it in the delivery log where it appears alongside live deliveries. Use it whenever you add a destination or change its URL. Nango-routed destinations return 422 here by design — those verify through the integration's own connection-test flow.

### Backfill history to destinations

Separate from the DLQ (which replays failures), the **Backfill history** button on the Destinations tab re-dispatches a timestamp window of successfully stored events to every matching destination — the "replay history" workflow after a tracking-plan fix or when wiring a new destination. `since` is required, an optional `until` bounds the window, an event-type filter narrows it, and `max events` is capped at 1000 per run, so a deep history is paged with successive backfills.

## 5. Common failure states

**Credential rotation.** A destination whose circuit tripped right after a secret rotation almost always means the receiver's verifier wasn't updated inside the 7-day dual-sign window — future deliveries fail signature checks at the receiver. Rotate again and update the receiver before the window closes this time. On the source side, a revoked ingest secret fails inbound HMAC verification immediately; keep an overlap when you rotate.

**Destination outage.** Deliveries fail on non-2xx, timeouts, connection refusals, or TLS errors. After five consecutive failures the circuit opens and new dispatches stop; failed deliveries accumulate in the DLQ. Once the outage ends, the first successful delivery auto-closes the circuit — or click **Reset** to close it immediately, then **Replay failed** from the DLQ group header to drain the backlog.

**Nango OAuth failures.** A destination connected via the Nango card grid (HubSpot, Salesforce, Braze, and the rest of the `(via Nango)` list) shows a **Connected** badge on its card once OAuth completes; the card flips to **Re-authenticate** when tokens expire or are revoked. Re-authenticate from the card — the subscriptions table row is not where OAuth state heals.

**Test event 422 on a Nango destination.** The synchronous test dispatch is intentionally blocked for Nango-routed destinations. Use the integration's own settings page to verify connectivity instead.

**Events not reaching one destination but passing another.** The per-subscription event filter is the first thing to check: a destination that subscribes to `contact.*` only will never see `message.*` events even while a sibling destination receives them. The Source and global DLQ verify ingest-side health; the destination's own settings own its filter.

## 6. Role gating

Every mutation on this page — mint / revoke ingest secrets, create / rotate / delete destinations, reset circuits, retry or replay deliveries, and run backfills — is gated to **owner, admin, or developer** roles. Members and viewers can read the page but cannot change the flow configuration. Design your team's split accordingly: typically developers own the source secret lifecycle, while admins own destination subscriptions; either role can perform both.

## See also

* [Sign CDP ingest requests without a client SDK](/guides/cdp-ingest-signing) — the exact HMAC contract your ingest callers implement
* [CDP tracking plan](/guides/cdp-tracking-plan) — declare the events the source-side ingest endpoint accepts
* [CDP event debugger and DLQ](/guides/cdp-event-debugger-and-dlq) — tail the inbound stream and replay failed destination deliveries
* [CDP data catalog and identity rules](/guides/cdp-data-catalog-and-identity-rules) — governance surfaces on the same page
* [CDP event model](/concepts/cdp-event-model) — the event shape both sides of the console carry
