Keeping Stytch and my Database in sync

I’ve been exploring stytch for B2B auth and love the fact that with the JavaScript SDK, I can run my auth entirely “serverless”, i.e. don’t need any API endpoints on my backend but can run the auth entirely through stytch directly.

However, at some point I need to sync newly created users into my database, or update my database with changes made e.g. in the stytch Dashboard.

I know this has been asked before in similar terms, but I’d like to better understand the available options.

If I run auth through my own API to trigger database updates, then (i) how can I still make use of the Stytch Dashboard, and (ii) can I still use the JavaScript SDK or do I need to implement my own functions for cookie management etc based on my own backend API?

I think my ideal scenario would be some sort of webhook from Stytch to react to changes made through the Dashboard with “good-enough” consistency, and handling user creation (where consistency really is important - you don’t want a user self-onboarding to an Org via discovery only to then hit errors because the database hasn’t updated yet) specially via application logic.

That said, I understand that there are currently not webhooks from Stytch. How do customers usually go about using the Stytch Dashboard without getting into an inconsistent state with their DB and causing bugs?

Hey Henrik,

Thanks for posting!

can I still use the JavaScript SDK or do I need to implement my own functions for cookie management etc based on my own backend API?

Yes - there are many ways to integrate with Stytch, and you can definitely still use the JS SDK to manage cookies even if you’re using some backend Stytch API functionality, or just using your own backend to hook into your DB based on events that occur on your frontend.

A few high level questions to help us better understand what the best path might look like here:

  1. What Stytch Member information do you need to store in your own database?
  2. Are you able to provide a bit more context on the reason you’d like to check Stytch Member data against your own DB rather than on the Stytch Member object itself, and what sort of controls you’re looking to put in place that leverage your own database?
  3. Would it be possible to just link the identifiers, e.g. store the Stytch member_id and organization_id in your own database, and the identifier for your own database on the Stytch User object (in Member metadata), or do you need access to additional Stytch Member data in your own DB without hitting Stytch servers (e.g. calling our Get Member endpoint with the stored identifier)?

you don’t want a user self-onboarding to an Org via discovery only to then hit errors because the database hasn’t updated yet

Can you describe the failure case a bit more here, and what you’d like to verify against your own database before allowing a Discovery flow login? Are you looking to only allow invited users to join Organizations, or something else?

The general mechanism for controlling how a member can join, and who can join is with Organization authentication settings.

For instance, if you would like to disallow JIT provisioning and only allow invited members to join, you might:

  1. Set email_jit_provisioning to NOT_ALLOWED and email_invites to ALLOWED or RESTRICTED
  2. Only invite Members via invite Email Magic Links, adding the Member data to your own internal database when you invite them

If you do want to allow email JIT provisioning during Discovery logins, then you may want do something like:

  1. Set email_jit_provisioning to RESTRICTED, allowing Members to be created and join Organizations without them being explicitly invited or already existing in your database,
  2. Add these Members to your own database once they’re created by making calls to your backend API when the relevant actions have occurred on the frontend (for instance, on discover.intermediateSessions.exchange() calls during a Discovery flow).

How do customers usually go about using the Stytch Dashboard without getting into an inconsistent state with their DB and causing bugs?

We don’t currently provide any hooks for Dashboard actions similar to our frontend JS SDK hooks, so there isn’t a great way to automatically hook into such actions.

If you expect to be performing Member management in your Stytch Dashboard and need to sync those changes, the best way to do this may be to have your own backend run a cron job or similar on some cadence to keep the two in sync. That said, this likely depends on exactly what kind of data you need to keep in sync, and at what point this will be checked by your application.

Thanks, that’s helpful. I feel like I might be trying to do something off the beaten path here and am happy to revise my architecture - but having member info in my DB seems like the most obvious approach to me:

The member id for foreign key constraints, (some of) the custom trusted metadata (I have a team_id field for an extra level in the multi-tenant hierarchy), and the member’s name & profile image. That’s because these are things I need for some API requests and I want to avoid the extra round-trip to Stytch and application-side join to fetch those details.

Some features (such as showing collaborators on a document) require me to list a set of members with their name and profile image in an efficient way. These are part of the member info from Stytch.

Yes for some of the data, but for things like name & image I’d prefer to have those managed by stytch (since these details could e.g. come from OAuth / SCIM / …). Though I’m sensing that’s not the architecture that people usually go for?


Sorry yes: Consider the case where I am using the JavaScript SDK in my frontend and have user self-onboarding enabled. A user comes in e.g. via the email magic link discovery flow, and joins an organization that they are eligible to join. This creates a new member in Stytch, and the user is forward to my application. Now assume that this application page relies on accessing member info from my DB. If Stytch hasn’t synced to my DB yet, then I will be in an inconsistent state: Authentication tells me this user should exist, but my database doesn’t know about them. Hence it’s not possible to implement user onboarding using (hypothetical) Webhooks from Stytch, ie. this flow needs to be routed through my backend anyway.

I guess I can do this by routing token exchange via my own backend endpoint, which then sets the stytch_session_jwt or stytch_session cookies for the client-side SDK to pick up?


I see. That’s somewhat unfortunate but should be well workable at my expected scale.

Hey Henrik!

That’s because these are things I need for some API requests and I want to avoid the extra round-trip to Stytch and application-side join to fetch those details.

Some features (such as showing collaborators on a document) require me to list a set of members with their name and profile image in an efficient way. These are part of the member info from Stytch.

Got it, that all makes sense!

Yes for some of the data, but for things like name & image I’d prefer to have those managed by stytch (since these details could e.g. come from OAuth / SCIM / …). Though I’m sensing that’s not the architecture that people usually go for?

I think most customers rely on Stytch Member objects (including Member trusted_metadata and untrusted_metadata) to store a lot/ most of their user data. That said, there are definitely use cases where additional user data needs to be stored in a separate DB. The right approach likely just depends on the specifics of your application, and in your case, it does sound like a hybrid approach (some data stored in Stytch Members, some stored in your DB) may be the way to go.

I guess I can do this by routing token exchange via my own backend endpoint, which then sets the stytch_session_jwt or stytch_session cookies for the client-side SDK to pick up?

In this case, I think the most common solution is to populate your DB with the new user’s data upon calling our frontend discovery.intermediateSessions.exchange or discovery.organizations.create methods (essentially, whenever the user is actually added to an Organization and a new Member is created). In other words, you’d make a call to your backend as soon as you receive a successful response from either of those two methods, and your backend would then add the necessary data to your DB (if it doesn’t exist already). You generally should be able to keep the authentication calls on the frontend in this case.

Does that make sense in the context of your application?

Thank you, that makes sense. I was attempting to make this atomic but now realize that’s unnecessary if I gate redirection to the main application to happen only after the user is created, after having first authenticated successfully.

Hey Henrik,

if I gate redirection to the main application to happen only after the user is created, after having first authenticated successfully

Awesome, sounds good - that’s exactly what we’d generally recommend for a sign up/Discovery flow!

Let us know if any other questions come up while you’re implementing!