links.10x.in/docs/end-user/playbooks/ops-lab-personalization-campaign-studio Published:

Ops Lab Playbook: Personalization + Campaign Studio

Last updated: 2026-03-08

1. Purpose and when to use this

Use this module to create campaigns, upsert personalization rules, and validate route outcomes before launch.

2. User roles and auth modes

  • [Creator] [Operator] JWT: campaign and personalization control-plane actions.
  • [Operator] PAT: scoped automation checks for public-handle personalization routes.
  • [Escalation] publish-control actions moved to Playbooks escalation boundaries.

3. Prerequisites checklist

  • Primer completed: Onboarding and API Primer
  • HANDLE, JWT_TOKEN configured
  • Optional PAT_TOKEN for scope validation
  • Existing link slug for route preview

4. UI onboarding flow

  1. Open https://app.10x.in/apps/personalization.
  2. Create campaign with explicit goal and status.
  3. Upsert a personalization rule (for example country-specific variant).
  4. Preview route decision for matching and non-matching contexts.
  5. Run campaign conversion test.

5. API workflow map

  1. PC-01: POST /v2/handles/{handle}/campaigns (JWT)
  2. PC-02: PUT /v2/handles/{handle}/personalization-rules/{ruleId} (JWT)
  3. PC-03: POST /v2/handles/{handle}/links/{slug}/route-preview (JWT)
  4. PC-04: POST /v2/handles/{handle}/campaigns/{campaignId}/test-conversion (JWT)
  5. PC-05: scoped PAT negative check (403) on public personalization mutation

6. cURL examples

Set module variables:

export CAMPAIGN_ID="spring-launch"
export RULE_ID="us-variant"
export SLUG="launch"

PC-01 Create campaign

curl -sS -X POST "${API_BASE}/v2/handles/${HANDLE}/campaigns" \
  -H "authorization: Bearer ${JWT_TOKEN}" \
  -H 'content-type: application/json' \
  -d '{"campaignId":"'"${CAMPAIGN_ID}"'","goalType":"PRODUCT_SALE","status":"ACTIVE"}'

PC-02 Upsert personalization rule

curl -sS -X PUT "${API_BASE}/v2/handles/${HANDLE}/personalization-rules/${RULE_ID}" \
  -H "authorization: Bearer ${JWT_TOKEN}" \
  -H 'content-type: application/json' \
  -d '{
    "enabled": true,
    "when": {"countryIn":["US"]},
    "variant": {"id":"us_variant","destinationUrl":"https://example.com/us"}
  }'

PC-03 Preview personalized route

curl -sS -X POST "${API_BASE}/v2/handles/${HANDLE}/links/${SLUG}/route-preview" \
  -H "authorization: Bearer ${JWT_TOKEN}" \
  -H 'content-type: application/json' \
  -d '{"country":"US","device":"desktop","source":"email","campaign":"spring"}'

PC-05 Scoped PAT negative test (expected 403)

curl -sS -X PUT "${API_BASE}/v2/public/handles/${HANDLE}/personalization-rules/${RULE_ID}" \
  -H "authorization: Bearer ${PAT_TOKEN}" \
  -H 'content-type: application/json' \
  -d '{"enabled":true,"when":{"countryIn":["US"]},"variant":{"id":"us_variant","destinationUrl":"https://example.com"}}'

7. Expected success outputs and verification checks

  • Campaign create returns 201 and campaign identifier.
  • Personalization rule persists and appears in subsequent previews.
  • Route preview returns matched variant where conditions apply.
  • PAT negative test returns deterministic 403 insufficient_scope when intended.

8. Failure modes and remediation

  • 403 insufficient_scope for PAT route writes:
  • Remediation: issue PAT with required personalization/tracking scopes.
  • 403 insufficient_role for JWT mutations:
  • Remediation: run as handle owner/operator with required role.
  • Route preview does not match expected variant:
  • Remediation: verify rule conditions and priority ordering.

9. Async behavior notes

  • Campaign and personalization writes are synchronous (SYNC).
  • Conversion test may fan out to async campaign signals via background processing.

10. Related links