Pre-Launch Checklist

Pre-Launch Production Checklist

Run these 8 tests before pointing real users at your integration. Most take seconds; a few involve waiting for a JWT to expire. Run this checklist after your LyticaLabs operator completes their onboarding steps.

Prerequisites

  •  Partner has received the welcome packet (slug, embed URL, API key, allowed domains, branding display name).
  •  Partner has registered their public JWK with LyticaLabs.
  •  At least one customer org provisioned via POST /api/v1/cp/orgs.
  •  Partner has wired <MarliWidget> and /api/marli-token mint endpoint.
  •  Partner is testing from one of the registered allowedDomains.

1Iframe Loads

Open your product page that mounts <MarliWidget> in a real browser (Chrome / Firefox / Safari). Open DevTools → Network panel. Reload.

Pass criteria

  •  Iframe network entry for https://alpha.lyticalabs.ai/embed/cp/{slug} returns 200.
  •  No CSP error in the console ("Refused to display in a frame…").
  •  Iframe paints — you see "Connecting to {displayName}…" then the chat shell.
SymptomLikely CauseFix
"Refused to frame…" in consoleCurrent origin not in allowedDomainsOperator: add the origin in admin UI
"Marli is unavailable" inert pagePartner row missing or suspendedOperator: check admin UI
Stalls at "Connecting…"postMessage allow-list rejectingCheck allowedDomains are full origins (https://app.foo.com)

2JWT Mint Endpoint Works

From your backend (curl or test runner) hit POST /api/marli-token with a logged-in user session.

Pass criteria

  •  Response is 200 application/json with {"jwt": "eyJ..."}.
  •  JWT decodes to {alg, kid} header + {iss, iat, exp, partnerOrgId, userId} payload.
  •  iss matches your registered slug.
  •  exp - iat is between 300 and 900 seconds (5–15 min TTL).

Fail:any 4xx/5xx response. Common causes: missing env vars, private JWK isn't valid JSON, or kid doesn't match registration.

3Chat Round-Trip

Sign into the partner product as a real user belonging to a provisioned customer org. Open the Marli panel. Send: "ping".

Pass criteria

  •  Marli's response streams in within ~2 seconds.
  •  Conversation persists through page refresh (subject to chat history persistence).
SymptomLikely CauseFix
"Account not found…"partnerOrgId not provisionedRun the provisioning curl for that org id
"Configuration error…"PARTNER_JWT_MISSING_CLAIMSCheck your mint endpoint payload
"Reconnecting…" never resolvesJWT signature failing verificationVerify private JWK matches the public JWK uploaded
5xx on /api/v1/cp/marli/agentServer-side bugFile with LyticaLabs technical contact

4JWT Expiry → Automatic Refresh

Without closing the iframe, leave the page idle for slightly longer than your JWT's TTL (e.g. 6 minutes for 5-minute tokens). Send another message.

Pass criteria

  •  First request fails 401 PARTNER_JWT_EXPIRED.
  •  You see "Reconnecting to {displayName}…" briefly.
  •  SDK automatically calls your mint endpoint once.
  •  Fresh JWT is delivered and the message goes through.

Fail:if the iframe locks into "Service is degraded" — your mint endpoint may be returning errors and the iframe burned through its retry budget.

5CSP Frame-Ancestors Enforcement

Try mounting the iframe from a domain not in your registered allowedDomains (e.g. localhost:9999).

Pass criteria

  •  Browser refuses to display the iframe — console shows "Refused to display in a frame because an ancestor violates…".
  •  No content paints.
Security boundary: If a non-allowed origin can paint the iframe, the CSP override is broken — file with LyticaLabs immediately.

6Suspended Partner Produces Inert UXOptional

Have your LyticaLabs operator flip your partner status from active to suspended in the admin UI. Open the iframe.

Pass criteria

  •  Iframe shows "Marli is unavailable for {displayName}…"
  •  No chat input visible.
  •  Operator flips back to active → iframe recovers on next load.

7Customer Org IsolationOptional

Provision two customer orgs: customer-A and customer-B. Have a user from customer-A chat, then mint a JWT for the same user with partnerOrgId: customer-B.

Pass criteria

  •  No data from customer-A's chat history appears in customer-B's session.
  •  Usage for customer-B's message attributes to customer-B, not customer-A.

If you only have one customer org during pilot, skip — but run before scaling to multiple customers.

When All Tests Pass

You are ready for production traffic. Optional final steps:

  • Add Marli iframe success/failure metrics to your product's observability dashboard.
  • Brief your customer-success team on what end users will see for PARTNER_SUSPENDED/ "Account not found" / "Reconnecting…" / "Service is degraded" so they can field tickets without escalating to engineering.
  • Schedule a Day-7 review with LyticaLabs to look at usage patterns, error rates, and rough edges.

When Something Fails

FailureWho to Contact
Test 1 (iframe blocked, partner-row issue)LyticaLabs operator
Test 2 (mint endpoint)Partner engineering
Test 3 (chat round-trip — gateway error)LyticaLabs technical contact
Test 3 (chat round-trip — partner claim error)Partner engineering
Test 4 (refresh loop)Partner engineering or LyticaLabs
Test 5 (CSP not enforced)LyticaLabs — immediately (security issue)
Test 6 (inert-state UX)LyticaLabs
Test 7 (multi-tenant isolation broken)LyticaLabs — immediately (security issue)