Skip to main content

Personalization API

A two-sided surface:
  • Dashboard side (/api/v1/personalization/slots, this page) — owners and admins define content slots, variants, and rules.
  • SDK side (/sdk/personalize) — the customer’s website JS fetches the right variant for a given visitor / contact at runtime.
This page documents the dashboard side. Base path: /api/v1/personalization Authentication: Session JWT (owner / admin role).

Create a slot variant

POST /api/v1/personalization/slots A variant is keyed on slot + segment_label + variant, and only one active variant may exist per combination — creating a duplicate returns 409, so edit or deactivate the existing one first. Omit segment_label to define the default content every visitor sees when no segment-specific variant matches. content accepts formatting HTML; scripts, iframes, and inline event handlers are rejected with 422 because the SDK injects the markup into your site.

Update variants and rules

PATCH /api/v1/personalization/slots/{id} Partial update — send only the fields you want to change; at least one is required. Omitted fields keep their stored values. Set active: false to stop serving a variant without deleting it; priority is the tie-breaker when several variants match the same visitor (highest wins).

Runtime fetching is via the SDK endpoint

The slot definitions above are what the SDK serves. At runtime the embedded website JS calls /sdk/personalize (unauthenticated, project-keyed) with the visitor’s slot keys and segment context, and Orbit returns the winning variant per slot — your page then injects the returned markup. The dashboard-side endpoints on this page never carry that traffic; the SDK path is cached and rate-limited for page-view volume. Preview any slot for a sample contact before shipping it with GET /api/v1/personalization/slots/{slot}/preview.

Using the SDKs

Python (same call via the SDK’s escape hatch):
The Python SDK is core-scope — it wraps the 8 core resources (messaging, voice, contacts, campaigns, verify, numbers) and reaches everything else through the generic client.request() escape hatch above. See the Python SDK. Returns the typed ApiResponse envelope. See the SDK index at SDK quickstart.

See also