Marketing automation integration
This page is the one-stop reference for connecting an external marketing automation platform to PlaylogiQ CRM — contacts, segments, messaging, automations, metrics, webhooks, rate limits, sandbox and compliance. It maps each capability to a concrete endpoint. The machine-readable contract is the OpenAPI spec; this page is the human guide.
1. REST API, base URL & docs
- Base URL:
https://crm-api.logiqdesk.com/api/v1(all paths below are relative to it). - OpenAPI 3.1 spec:
GET /api/v1/openapi.json— import it into Postman / Insomnia / an SDK generator. - Health check (public, no auth):
GET /api/v1/health. - Developer docs: this portal.
All responses are JSON { data: … } on success, or { error, code } on failure
(UNAUTHORIZED, FORBIDDEN, BAD_REQUEST, NOT_FOUND, CONFLICT,
RATE_LIMITED, INTERNAL_ERROR).
2. Authentication
Operator API keys (prefix plq_). There is no OAuth2 — a long-lived
secret key is the credential.
- Send it as
x-api-key: plq_…(preferred), orAuthorization: Bearer plq_…, or?api_key=plq_…for senders that cannot set headers. - Generate / revoke in the dashboard: Settings → Integrations → API keys (super-admin). Only a SHA-256 hash is stored, so the plaintext key is shown once — store it. There is no auto-rotation: to “renew”, mint a new key and revoke the old one.
- Scopes (least privilege): a key carries scopes —
events:write(ingest events),read(all GETs),write(all creates/updates/deletes). An empty scope set = full access. Areadkey cannot mutate; an ingest key can only push events. - Brand pinning: a key can be pinned to one brand (recommended) — it then
reads/writes only that brand and ignores any
x-brandhint. A tenant-wide key accepts an optionalx-brandheader (or?brand=, a brand id or slug; default brand when omitted).
3. Operations
Contacts / players
| Operation | Endpoint |
|---|---|
Create / update (upsert by external_id) | POST /players |
| Read one | GET /players/{id} |
List / search (by email or external_id, ?status=, ?brand=) | GET /players |
| Update (status / email / phone / metadata) | PATCH /players/{id} |
| Per-contact messaging history + metrics | GET /players/{id}/messages |
| Recommended next action | GET /players/{id}/next-best-action |
Players carry identity, consent and a financial snapshot; event-driven metrics (LTV, deposits, lifecycle) are derived by the platform from the event stream. There is no hard-delete endpoint — GDPR erasure is handled operator-side (see §7).
Segments / lists
| Operation | Endpoint |
|---|---|
| List | GET /segments |
| Create (dynamic rule-based or static) | POST /segments |
| Get / update rules / delete | GET | PATCH | DELETE /segments/{id} |
| List members | GET /segments/{id}/members |
| Add / remove contacts (static segments) | POST | DELETE /segments/{id}/members |
| Export membership as an audience (JSON/CSV, cursor-paged) | GET /segments/{id}/export |
A dynamic segment’s membership is computed from its rule tree by the worker;
a static segment is an explicit list you manage via the members endpoints
(identify contacts by player_ids and/or operator external_ids).
Email / SMS / push messaging
| Operation | Endpoint |
|---|---|
| Templates: list / create / get / update / delete | … /notifications/templates |
| Single send to one player | POST /notifications/send |
| Campaigns: list / create | GET | POST /campaigns |
| Campaign get / update / status transitions / cancel | GET | PATCH | DELETE /campaigns/{id} |
| A/B testing | campaign variants (weighted) + results in the dashboard |
Channels: email, telegram, push, in_app (SMS/WhatsApp templates exist as
template channels). POST /notifications/send enqueues a message; the worker
delivers it (SMTP / Bot API / Web Push). Launching/scheduling a campaign send is
driven by its status + schedule — set via PATCH /campaigns/{id}.
Automations / journeys
| Operation | Endpoint |
|---|---|
| List / create (draft) | GET | POST /journeys |
| Get / update graph / activate / archive | GET | PATCH | DELETE /journeys/{id} |
| Enroll players (manual journeys) | POST /journeys/{id}/enroll |
| Unenroll players | POST /journeys/{id}/unenroll |
Journeys (welcome, win-back, reactivation, …) are node graphs. Event- and
segment-entry journeys enroll automatically; manual journeys are enrolled
via the enroll endpoint (a segment and/or explicit player_ids).
Metrics
| Scope | Endpoint |
|---|---|
| Per campaign (sent/delivered/opened/clicked/converted/failed/bounced + rates) | GET /campaigns/{id}/stats |
| Per contact (message history + open/click rates) | GET /players/{id}/messages |
| Account KPIs | GET /analytics/summary |
| Time series (players + events/day) | GET /analytics/timeseries |
| Revenue breakdowns | GET /analytics/revenue |
| Cohort retention / profile | GET /analytics/cohorts |
| Ad-hoc metric × dimension | GET /reports/run |
| Bulk export for BI/warehouse (players/events/transactions) | GET /export/{dataset} |
GET /campaigns/{id}/stats returns both totals and derived rates
(delivery_rate, open_rate, click_rate, click_to_open_rate,
bounce_rate, conversion_rate). Unsubscribes are tracked as suppression +
the email.unsubscribed webhook.
4. Webhooks
Outbound webhooks notify your systems when something happens. Manage them via
the dashboard or the REST API (GET/POST /webhooks,
GET/PATCH/DELETE /webhooks/{id}, GET /webhooks/{id}/deliveries,
POST /webhooks/{id}/ping). Full details, event catalog and signature
verification: Outbound webhooks.
Events relevant to marketing automation: message.delivered, message.opened,
message.clicked, message.bounced, email.unsubscribed, plus player.*,
segment.recomputed, campaign.created, bonus.granted.
Each delivery is an HMAC-SHA256-signed POST — header
X-PlaylogiQ-Signature: sha256=<hex> over the raw body, keyed by the endpoint’s
secret. Delivery is at-least-once with exponential backoff (≈1m → 5m → 15m →
1h, up to 5 attempts) and a delivery log.
5. Rate limits
Per-tenant, fixed 60-second window, two tiers:
| Tier | Default budget | Applies to |
|---|---|---|
ingest | 6000 req/min | POST /events, POST /ingest, push subscribe |
api | 1200 req/min | everything else |
Over budget → 429 with X-RateLimit-Limit / X-RateLimit-Remaining /
X-RateLimit-Reset and Retry-After. Event ingestion batches up to 100
events per request. (Delivery throughput — emails/day etc. — is bounded by the
channel provider, not the API.)
6. Sandbox / test mode
There is no separate sandbox host. Test safely with either:
- A dedicated test brand + a brand-pinned key. Create a
sandboxbrand, mint a key pinned to it, and all writes stay isolated to that brand — nothing touches production brands. - Dry-run a send: add
X-PlaylogiQ-Test: truetoPOST /notifications/send. The request is fully validated (player, template, channel) but nothing is enqueued or delivered; the response is{ queued: false, test: true, … }. - Test a webhook without waiting for a real event:
POST /webhooks/{id}/ping.
7. Compliance
PlaylogiQ handles the opt-out/consent plumbing; you supply consent on ingest:
- Consent travels on
POST /players(marketing_consent,consent_channels) and is editable per player; per-channel consent + frequency caps are enforced by the delivery worker. - One-click unsubscribe: every marketing email carries a signed
{{unsubscribe_url}}. Confirming it suppresses the address (suppression_list), clears marketing consent, and firesemail.unsubscribed. The worker never mails a suppressed/unconsented address. - GDPR / data requests (export, erasure) are handled operator-side by the platform team — there is no public erase endpoint, so route those to your PlaylogiQ operator.
- Chile / jurisdiction-specific marketing rules: the platform provides the consent + suppression primitives; the operator configures policy. Confirm the specific legal requirements with your PlaylogiQ operator for your market.
In short: the opt-out/consent/suppression mechanics are the platform’s; you must still send correct consent on ingest and honour the suppression signal (the
email.unsubscribedwebhook) in your own system.