K
Kinde•2w ago
__maxom__

Adding an existing Kinde user to a new organisation

Hi, Thanks for a wonderful product. This is more of a generic question that I'm unable to find an answer to. I'm currently building a B2B2C SaaS application and the business admins can add users(clients) to their business so that they can login to the business dashboard. What I have noticed is that if a user already exists in Kinde, and I want to try to add a user from the organization, I get a "Email already in use" error. (Example a user is already a client with one business and is becoming a client in another business). What is the best way to deal with this scenario ? Do I have to write a custom logic to check if the user exists in Kinde. If yes, add the user to the organisation. If not, then create an user and then add them to the organisation ? Or is there a way where Kinde as a platform can do this check ? Check if user exists in pool, add to org if yes. Or create a new user and add to org ? Thanks.
50 Replies
__maxom__
__maxom__OP•2w ago
Adding on to this, when a user is added by a business, is there a way to send user invitation emails from Kinde or is this an additional workflow that we have to build ?
Ages
Ages•2w ago
Hey there Maxom, I'm confident this is something that can be done - but HOW it can be done might depend on a few things. Can you tell us what SDK / framework you are using, how your B2B's are set up in terms of auth (e.g. are they SAML, SSO, Passwordless, etc.). How do you onboard businesses? Do they bring their own SSO or do you supply the auth via Kinde?

On the other question, there is currently no email invitation OOTB, but you can use webhooks to trigger a third party application (like mailchimp) to send one when a user signs up. We also have a feature called workflows (just finishing the beta) about to release that will be able to do this as well. Here's some links to docs.
https://docs.kinde.com/integrate/webhooks/about-webhooks/
https://kinde.notion.site/Beta-Workflows-docs-137d97b0d20580269a53f42525252087 You might find the #Kinde-AI channel useful as well, where you can query the docs. Or ask more here in the support channel 🙂
__maxom__
__maxom__OP•2w ago
Hi Claire, I'm using the React SDK with React19. I have done a force install for now as the Kinde React SDK does not have React 19 as its dependencies. Auth is handled completely by Kinde. For now, businesses can join the platform by signing up with email password or google. Once logged in, I check if an org_code exists in the access token. If it does not exist, then I trigger an onboarding flow to capture additional details and call the Kinde Management API's to create a new org, add this user to the org and assign the user an "owner" role. After onboarding, they can setup their business in the app dashboard, invite users, grant permissions to the users etc. So when testing invite users. I was testing a scenario where there are 2 businesses A, B. A user is a member/client of business A so this user's email already exists in Kinde. If the user wants to use the same email with business B, then I get the email errors. As this is a B2B2C app, the business B does not have to know if the user is already a part of my platform with another business. My question is around can Kinde handle this as a built in functionality or do I have to write some logic to achieve this ?
Ages
Ages•2w ago
Thanks a lot for the additional info and the description of the flow. I'll need to consult our react dev to see if there's a way to handle this for you. It is a common scenario for B2B2C to need this, so I'll see what they say and get back to you. Perhaps someone in the community sees this and has overcome a similar issue. Actually I think it might be a matter of passing the org code in the sign up flow. So if your business customers send invitations that pass the org code in the token, they should be able to add the user without issue. Here's the React function https://docs.kinde.com/developer-tools/sdks/frontend/react-sdk/#sign-upsign-in-users-to-organizations Also we are about to release the new React SDK - it is in final testing.
__maxom__
__maxom__OP•2w ago
So essentially we need to build an external flow where a business adds a user, we send an invitation to login with any email but the login() method should have the org code in it. So when the user tries to login, then they automatically get added into the org ?
__maxom__
__maxom__OP•2w ago
When I try adding a user from the Kinde Management console, Home > Organizations > Business > Users > Add User. Fill in the email and select the organization, then save. I get the same error. So this will not work from the Kinde UI. This is my sandbox:
No description
__maxom__
__maxom__OP•2w ago
Any ETA on this ? We are currently still developing the application and intending to launch in a month for private beta. Hoping to get this update and still have some time to do proper testing before we release. For now I have force installed the the React SDK which is causing conflicts and the functionality seems to work for a majority of things apart from a few (either the functionality does not work or I am unable to find proper information on how to get it to work) Example: https://discord.com/channels/1070212618549219328/1343107436780851281
Ages
Ages•2w ago
We are hoping this week for React.
__maxom__
__maxom__OP•2w ago
Thanks Claire
Ages
Ages•2w ago
__maxom__
__maxom__OP•2w ago
Hi Claire, does this updated package address the issue here ? https://discord.com/channels/1070212618549219328/1343107436780851281 Currently passing in the org_code to the login() method explicitly solves the issue but I believe if we have refreshed the user claims and invalidated caches in the backend using the Kinde Management API's, on page reload, new access tokens should be generated to give context about organizations, roles, permissions etc Or how to handle scenarios where a user is logged in but the admin has changed their permissions, how to get the updated permissions reflected in user’s token
Ages
Ages•2w ago
Another dev is going to reply about the org code issue. On the React, I don't know if it solves another user's specific issue. They will need to try it and see. I know a lot of work was done on refresh issues, though. Hey maxom, have you tried going to the user and then clicking the checkboxes under organizations - that should add users to the org User details => Edit organizations
__maxom__
__maxom__OP•2w ago
Hi Peter, it works if I assign an organization from the user but it does not work if I try to assign user from the organization For my current use case B2B2C model, I need to have the capability to add users from the organization And it seems this functionality does not work with Kinde Not from the console I have even tried using the management API And still the same error
__maxom__
__maxom__OP•2w ago
My payload for the Create User API looks like this and I'm providing the org_code as a part of the API body:
{
"profile": {
"given_name": "John",
"family_name": "Doe"
},
"organization_code": "org_d976e3232xxxx",
"provided_id": "email",
"identities": [
{
"type": "email",
"details": {
"email": "[email protected]"
}
}
]
}
{
"profile": {
"given_name": "John",
"family_name": "Doe"
},
"organization_code": "org_d976e3232xxxx",
"provided_id": "email",
"identities": [
{
"type": "email",
"details": {
"email": "[email protected]"
}
}
]
}
And when I hit the Kinde management API with the above body, which is a valid one based on https://docs.kinde.com/kinde-apis/management/#tag/users/post/api/v1/user, I get the error:
{
"status": 400,
"statusText": "Bad Request",
"message": {
"errors": [
{
"code": "PROVIDED_ID_ALREADY_EXISTS",
"message": "An existing user was found against the provided id."
},
{
"code": "USER_ALREADY_EXISTS",
"message": "An existing user was found against the identity data provided."
}
]
}
}
{
"status": 400,
"statusText": "Bad Request",
"message": {
"errors": [
{
"code": "PROVIDED_ID_ALREADY_EXISTS",
"message": "An existing user was found against the provided id."
},
{
"code": "USER_ALREADY_EXISTS",
"message": "An existing user was found against the identity data provided."
}
]
}
}
So for any request, I need to first check if the user already exists in the Kinde global pool and if they do not exist, then create user or if they exists add user to organization ? Adding on top of this, your Get User Kinde Management API requires the userid in "kp_xxx" format. This is a required parameter. So how would I even check if the user exists based on email id when I do not know their user_id ? It feels like I need to add a custom db component which stores the email -> userid mapping and then use this db to query the user id first, then use this user id to call Get User to see if they exist or not. If they exist make an API call to add user to org, else make API call to create user. All this seems super confusing. Kinde advertises B2B2C auth can be handled with Kinde: https://docs.kinde.com/build/set-up-options/kinde-business-model/#you-provide-services-to-companies-and-their-customers-b2b2c So how can I achieve this ?
Kinde docs
Kinde for different business models
Our developer tools provide everything you need to get started with Kinde.
Kinde docs
Kinde Management API
The management API is for managing your Kinde account. Most things that can be done via the Kinde admin UI can be done with this API
__maxom__
__maxom__OP•2w ago
Hi Claire, that is also a thread raised by me. All of these issues kind of seem interlinked with each other
CB_Kinde
CB_Kinde•2w ago
Hi Maxom. I think that you are expecting Kinde to treat organizations like empty buckets that you put users in. Kinde does not work this way. Users are added to Kinde and can exist in multiple organizations. Identities are managed at the top level, not per org. That's why you are getting an error when you try to add an existing user. We do this so that we can support multiple models where a user might be a buyer or a selller (in a marketplace for example). And might also be part of a business, as well as a user of a nother business. For your case, once a user is added, and you want them to belong to other organizations, you just add them to that organization. Can you explain a bit more fully what the end goal is? Do you just want your business customers (orgs) to be able to add users? Well they can, if they pass the org code with the sign in and if a user exists they will be added to the oirg, if they do not exist, they will be added to Kinde and the org. In addition, how are users being added? Via API, self-sign-up? Manually added? How do you want your business customers to add users?
Ages
Ages•2w ago
Hey Maxom, wanted to also ask how you're using React 19 - are you creating the app from scratch or working with a framework (next.js / react-router)?
__maxom__
__maxom__OP•2w ago
Hi @CB_Kinde , thanks for your response. To give you a bit more context, I’m building a club management SaaS applications. The idea is various clubs can signup to my application and each club can manage their own members, post events, timetables etc. Members can login to my portal. If they are associated with one club, they’ll view the club specific information directly. If the member is associated with more than one club, then they can choose which club they want to login to (built in Kinde org chooser UI) and they’ll be logged into that club. Now, as each club can add their own members, I want to provide the club owners a functionality to add users to their club. They will click a add member button in my UI with all the details which will interact with my backend API. My backend API interacts with the Kinde management API. Now a member or a user can be a member of multiple clubs who are all using my application for their club management. If a member joins a club say A which uses my software, the user does not exist in Kinde yet. With the create user management API call, I can successfully create the user in Kinde and add the user to the org and send email to the member. Now say the same user is wants to join another club B with the same email and B also uses my software. How do I add them to this new org ? If I use the create user API with the org code, it throws the error as provided above. Members are added into my application by the clubs. Member cannot join a club directly. If someone tries to sign up from my application, they’ll be treated as a club owner Me as an application does not manage users. Logically, it is like each club is its own tenant and each tenant can have its own users And a user can be a part of one or more orgs and due to security I cannot show a club if the user has previously signed up or used the same email with another org Hope that explains my use case It is a pure React (Vite) app + Tanstack Router + Kinde for auth Tech stack is React SPA deployed on S3 with cloudfront for static hosting. There is an API layer in between that interacts with the backend. The entire stack is on AWS
CB_Kinde
CB_Kinde•2w ago
Maxim not sure what endpoint is being hit when a new user request is sent and you get an error, but if your clubs hit this endpoint - https://docs.kinde.com/kinde-apis/management/#tag/organizations/post/api/v1/organizations/{org_code}/users And passes their org code, this should add the user to the org (and create the record in Kinde if there is not one)
Kinde docs
Kinde Management API
The management API is for managing your Kinde account. Most things that can be done via the Kinde admin UI can be done with this API
CB_Kinde
CB_Kinde•2w ago
@Peteswah can you verify?
__maxom__
__maxom__OP•2w ago
Kinde docs
Kinde Management API
The management API is for managing your Kinde account. Most things that can be done via the Kinde admin UI can be done with this API
__maxom__
__maxom__OP•2w ago
With the endpoint that you have shared, the assumption is that the user is already created as you have to pass the user_id as the args to the endpoint User id is a kp_xxxx id My question is around how do I determine if a user (email) exists in the first place ?
__maxom__
__maxom__OP•2w ago
You get user endpoint requires user id which is a kp_xxx id and not an email https://docs.kinde.com/kinde-apis/management/#tag/users/get/api/v1/user
Kinde docs
Kinde Management API
The management API is for managing your Kinde account. Most things that can be done via the Kinde admin UI can be done with this API
CB_Kinde
CB_Kinde•2w ago
Let's wait for Peter
__maxom__
__maxom__OP•2w ago
This works well if the user does not previously exist in Kinde. It creates user and adds to org
CB_Kinde
CB_Kinde•2w ago
My bad, you are right.
__maxom__
__maxom__OP•2w ago
The issue comes when the user already exist in Kinde
CB_Kinde
CB_Kinde•2w ago
Can you use GET /api/v1/[email protected] to check if a user exists and then if a response includes a user id, use post/api/v1/organizations/{org_code}/users (user exists, add to org) And if a user ID is not returned, use post/api/v1/user and include the org code in the request body
__maxom__
__maxom__OP•2w ago
Kinde docs
Kinde Management API
The management API is for managing your Kinde account. Most things that can be done via the Kinde admin UI can be done with this API
__maxom__
__maxom__OP•2w ago
Id is a required parameter
CB_Kinde
CB_Kinde•2w ago
No, you can use an email I think
__maxom__
__maxom__OP•2w ago
I was going through the API spec. I have shared the link. Can you please confirm? Id is mandatory which is a kp_xxx id according to your API spec The expand arg: Specify additional data to retrieve. Use "organizations" and/or "identities". You cannot provide email as an arg to this API
CB_Kinde
CB_Kinde•2w ago
What about using this endpoint GET /api/v1/users
__maxom__
__maxom__OP•2w ago
And I could not find any other API to retrieve user details based on email. But looking at the api responses, I believe email is a PK in your database hence it is not allowing duplicate emails for users I could give this a try but is this the most efficient way to do it ? It feels it is expensive operation from a compute standpoint
CB_Kinde
CB_Kinde•2w ago
It does what you need it to do - search users and filter by email Peter may have a better idea. I am out of ideas
__maxom__
__maxom__OP•2w ago
I’m also looking at application performance so I’m trying to avoid API’s calls with functionality like select * and then filter. Not sure about your backend implementation but I have noticed that API’s like get users have a higher response time compared to get user And I have to keep in mind that I need to chain this get users api call with another api call to effectively do what I’m trying to do
ev_kinde
ev_kinde•2w ago
Hi @maxom, I'm catching-up on your use-case, let me describe the data model Kinde uses to manage multi-tenancy first. In Kinde a user has a primary ID, starts with kp_, which is unique across your environment. A user can be associated starting from zero to many identities which are used for authentication. As an example user A can have an email identity and a Google social identity associated with them. Both those identities are uniquely identifying the user and cannot be attached to any other users. Then a user could belong to zero up to many organizations, which control multi-tenancy and user authorization. When you are referring to creating a user in the organization, it's more like adding an existing user to an organization. Ideally, you would have a record of the Kinde user ID in the database, and when inviting you could add that user to a separate organization. It is possible to filter users by email address via the API, here's the endpoint https://docs.kinde.com/kinde-apis/management/#tag/users/get/api/v1/users
__maxom__
__maxom__OP•2w ago
Hi @ev_kinde, as each org is like its own tenant, emails would be the primary mode to add users. My main question was around does Kinde have a built in mechanism is do this checks or do I have to do it manually in my backend logic And is using the Get users API call the most efficient way to do this ? As if I go straight to create user with org code, it throws errors
ev_kinde
ev_kinde•2w ago
Generally speaking Kinde operates with user ID as a unique identifier, as emails could change and are not very reliable as IDs. When you call the API to create a user and an existing user with the same email identity already exists, you'd get an error back. Kinde doesn't yet have a hosted user invite flow, it needs to be done via the API at the moment.
__maxom__
__maxom__OP•2w ago
Ok thanks for confirming So just to summarise. When we click on an add user button in UI and tries to add user with email: Make the following Kinde API calls: 1. get users with filter on email 2. If user does not exist, create user with org code as an argument 3. If user exists, add user to org Am I understanding this correctly?
ev_kinde
ev_kinde•2w ago
Yes, that's correct, the other option you could record Kinde user IDs in the database and know which user to add to an organization right away without calling the API. A sidenote, it's possible to directly switch an active user session between organization without re-authenticating or showing the organization switcher, you'd need to provide the org_code and if user is already authenticated, Kinde will switch their session and tokens to the new organization (doc https://docs.kinde.com/authenticate/manage-authentication/navigate-between-organizations/)
__maxom__
__maxom__OP•2w ago
Yup, that was the other thing… I need to ensure my users db table is in sync with Kinde As I populate my db using webhooks, I’m just afraid there could be scenarios where my db is out of sync sometimes with Kinde as interacting with Kinde is mainly apis and populating my db with users is using webhooks. So that is why I was trying to rely on Kinde apis to do my checks and balances I’ll probably do a db interaction first and then do kinde api checks as fallback
ev_kinde
ev_kinde•2w ago
The access token includes the sub claim, which will be the Kinde user ID, you could see an example in the JWT decoder https://kinde.com/tools/online-jwt-decoder/ Our SDKs contain helper methods on getting information from the tokens.
Kinde
Online JWT decoder
Leverage this tool to ensure that your JWT has the specific metadata and claims you anticipate or to analyze JWTs generated by a 3rd party.
ev_kinde
ev_kinde•2w ago
The access token will also include the currently authorized organization code and the user permissions assigned to the user related to that organization
__maxom__
__maxom__OP•2w ago
Sorry I’m a bit confused with this response. How does it relate to the issue in this thread ? The sub in the token would be of the user who is trying to add members right and not of the users we want to add are you referring to how to login a user to a different org ?
ev_kinde
ev_kinde•2w ago
Not really, I'm assuming your application operates based on the email addresses, while Kinde operates based on the unique user IDs. I was referring to the way of getting that user ID.
Ages
Ages•2w ago
I think Maxim is looking to grab the user based on an inputted email address so something like detecting if an email address is already in use

I think in this case you can use https://docs.kinde.com/kinde-apis/management/#tag/search to grab a user via their email if they exist
__maxom__
__maxom__OP•2w ago
I’m still confused by your last couple responses but all good. I understand what I need to do to cater to my scenario. Thanks you all with the support This or get users
Ages
Ages•2w ago
Then if the user needs to be added to an org you can use this API endpoint https://docs.kinde.com/kinde-apis/management/#tag/organizations/post/api/v1/organizations/{org_code}/users Yeah, I think with getting users you would then have to search through to see if a user with that email exists, which could be a problem if the number of users gets too large I think it might be best to go with search on email, which should then return the user id you need to add to the specific org
__maxom__
__maxom__OP•2w ago
Thanks Peter

Did you find this page helpful?