User Authentication & Enrollment Behavior

Controlling Loyalty Enrollment via the JWT

When a user is authenticated on your website, the Loyalty Web Kit (LWK) authenticates them automatically through the JWT (authToken) you generate server-side. The behavior of the LWK — whether it enrolls the user into your loyalty program, and whether it creates the contact in Splio — depends entirely on what you put in that JWT and on one configuration setting: block_auto_sub.

This article covers:

  1. Default behavior — automatically enroll any authenticated user.
  2. Controlling enrollment for opted-in users only — the two available options, and how they differ.

Default behavior: auto-enroll everyone

By default, the LWK is designed to automatically log in and enroll any authenticated user into your loyalty program the first time they access it.

Concretely, whenever the JWT you generate contains a contact_id (external_id in the JWT payload), the LWK will:

  1. Upsert the corresponding contact in your Splio universe (create it if it doesn't exist yet, update it otherwise).
  2. Check if that contact is already a member of the loyalty program.
  3. If not, automatically subscribe them to the program.

Keep in mind the following scenarios when adapting your website's user flow:

SituationLWK behavior
Authenticated, existing in Splio, already a member of your programUser is logged in and sees their loyalty data
Authenticated, existing in Splio, not yet a member of your programUser is logged in and automatically subscribed to the program
Authenticated, not existing in SplioContact is created in Splio and automatically subscribed to the program
Not authenticatedUser goes through the sign-in / sign-up page you configured (unconnected.signin / unconnected.signup), and should be redirected back to the LWK once authenticated
📘

If this default behavior fits your use case (any logged-in user should join the loyalty program), you don't need any extra configuration: just make sure to always include the contact_id in the JWT for every authenticated user.

Controlling enrollment for opted-in users only

If you manage your own internal opt-in flag (for example, a checkbox in your account settings or CRM) and only want opted-in users to join the loyalty program, you have two independent levers to achieve this. They act at different levels, don't block the same thing, and don't have the same operational cost — so it's important to understand how they differ before choosing one.

Omitting contact_id from the JWTEnabling block_auto_sub
Where it's controlledIn your backend, per request / per user, when you generate the JWTIn the LWK configuration, once, for all users of that configuration
Is the contact created/updated in Splio?No — never, for that userYes — always, as soon as a contact_id is present, regardless of this setting
Is the loyalty enrollment blocked?Yes, indirectly (the user is treated as anonymous)Yes, but only if the contact isn't already a member
Who enrolls the user into the loyalty program?Splio, automatically, the first time you send their contact_idYou — you must subscribe the contact to the program yourself (via API, or through whatever process feeds Splio)
What the user seesThe same experience as a non-authenticated visitorA dedicated "not a member" screen, linking to your sign-up page, until Splio has recorded their enrollment
ScopePer user, decided on your sideGlobal, applies to every user of this configuration

In short: omitting contact_id decides whether this user is even allowed to exist in Splio at all. block_auto_sub decides whether a contact that already exists (or was just created) is allowed to automatically join the loyalty program — and shifts the responsibility of actually enrolling that contact from Splio to you.

Option A — Omit contact_id for non-opted-in users

The recommended approach if you want full control and don't want Splio to know about non-opted-in users at all: control it on the JWT generation side, based on your own opt-in flag.

  • If the authenticated user is opted in: include their contact_id in the JWT, as usual. The LWK will upsert the contact and enroll them into the loyalty program.
  • If the authenticated user is not opted in: do not include the contact_id claim in the JWT (or generate the JWT as if the user were anonymous). The LWK will then treat them as a non-authenticated visitor: no contact upsert, no enrollment, and they'll go through the sign-in / sign-up flow you've configured.

This requires your backend to know the opt-in status before generating the JWT, but gives you full control without needing any specific configuration on the Splio side, and without any enrollment delay: as soon as contact_id is sent, the LWK enrolls the user immediately.

Option B — Enable block_auto_sub

Enable the block_auto_sub property in your LWK configuration if you want the LWK to never auto-enroll a contact who isn't already a member of your loyalty program.

When block_auto_sub is enabled:

  • If the contact is already a member of the loyalty program, they're logged in normally.
  • If the contact is not a member yet, the LWK will not auto-enroll them. Instead, the user is treated as not connected and shown a dedicated "not a member" screen, redirecting them to the sign-up page you've configured (unconnected.signup).
⚠️

Important nuance: block_auto_sub only blocks the automatic loyalty program enrollment. It does not prevent the contact record itself from being created or updated in Splio: as soon as a contact_id is present in the JWT, the corresponding contact is upserted in your Splio universe, independently of their loyalty program membership status.

⚠️

You become responsible for the enrollment. With block_auto_sub enabled, Splio no longer auto-enrolls the contact — you need to subscribe them to the loyalty program yourself, through whatever process feeds membership data into Splio. Until Splio has actually recorded that enrollment, the user keeps seeing the "not a member" screen, even after they've opted in on your side.

This matters if enrollment doesn't happen in real time. For example, if loyalty subscriptions are synced via a Datahub import running once every 24 hours, a user who opts in right after the last import will keep seeing "you're not a member" and won't access the LWK until the next import runs, up to 24 hours later.

We only recommend block_auto_sub if the enrollment is performed via direct, real-time API calls (e.g. right after the opt-in action, calling the loyalty subscription API synchronously). If your enrollment relies on a batch process (scheduled imports, Datahub, nightly syncs, etc.), prefer Option A instead: it enrolls the user instantly, with no dependency on your synchronization delay.

Which one should you use?

  • Use Option A if you never want Splio to have any record of non-opted-in users, or if your enrollment process isn't real-time (batch imports, scheduled syncs, etc.). It enrolls the user immediately, with no synchronization delay.
  • Use Option B only if it's fine for Splio to know about a contact (for other use cases, such as marketing automation) and your enrollment into the loyalty program happens through a direct, real-time API call. Otherwise, users may be stuck seeing the "not a member" screen until your next batch sync runs.
  • You can combine both: send contact_id only for opted-in users (Option A), and additionally enable block_auto_sub as a safety net in case a contact_id is ever sent by mistake for a non-opted-in user — in that case, the contact would still be created in Splio, but at least would not be auto-enrolled into the program.

Did this page help you?