From 7b0c7d6b4e4c730f14f2559ec056392d873dad4a Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Thu, 30 Apr 2026 17:04:00 +0600 Subject: [PATCH 01/14] Update the quick start page --- .../kinde-api/connect-to-kinde-api.mdx | 69 ++++++++++++------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx index e47ca8b39..d8918cbc0 100644 --- a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx @@ -1,9 +1,12 @@ --- page_id: 50284476-2442-414c-af20-01ed3ef4ca4e -title: Set up Kinde Management API access +title: Kinde Management API Quickstart Guide description: "Step-by-step guide to setting up M2M applications and authorizing them for Kinde Management API access with proper scopes" sidebar: order: 1 + label: "Kinde Management API Quickstart" +tableOfContents: + maxHeadingLevel: 3 relatedArticles: - 51899f7f-3436-46e0-9a1b-6ecc3603a0df - 6bf993fc-a195-4836-8eaf-133812be8876 @@ -28,43 +31,67 @@ keywords: - authorization - access token - machine to machine -updated: 2024-01-15 +updated: 2026-04-30 featured: false deprecated: false ai_summary: Step-by-step guide to setting up M2M applications and authorizing them for Kinde Management API access with proper scopes --- +The Kinde Management API let's you do everything you can do with the Kinde UI. It is useful for pragmatically managing your Kinde account and resources such as use in CI/CD pipelines. + In order to call the Kinde Management API, you will need a Kinde management API access token. These tokens are generated by using an authorized M2M application to call the Kinde token endpoint. This guide shows you how to set up a new machine to machine (M2M) application, and authorize it for Kinde Management API access. -## Step 1: Add a machine to machine application + -1. Go to **Settings > Applications**. -2. Select **Add Application**. The **Add application** dialog opens. -3. Give the application a name, and select **Machine to Machine** as the **Application type**. -4. Select **Save**. App keys - including Domain details, Client ID and Client Secret - are issued for the application. -5. Select **View details** on the new application and copy the app keys. You need these details to test or initiate access requests from your application or service to Kinde's API. See Step 4 below. +## Quickstart guide -## Step 2: Authorize the M2M application +### 1. Create a machine to machine application -Only authorized M2M applications are allowed to access the Kinde management API. Without this step you will receive an error when calling the Kinde management API. +1. Go to your Kinde dashboard and select **Add application**. +3. Give the application a name (e.g., "API Automation"), and select **Machine to Machine** as the application type. +4. Select **Save**. -1. Select **View details** on the M2M application you just created. -2. On the left, select **APIs**. -3. Select the three dots next to the Kinde Management API, then choose **Authorize application**. +### 2. Authorize and add scopes -## Step 3: Select scopes +1. On your application settings page, select **APIs**. +2. Select the three dots next to the **Kinde Management API**, then choose **Authorize application**. +3. Select the three dots again, now select **Manage scopes**. +4. Enable the scopes you want to include for this application. (e.g., `read:users`, `write:users`, `read:roles`, `write:roles`) -Each Kinde endpoint requires specific permissions to be present in the token, to grant access to it. These are known as scopes. If a scope is not in the access token, the API will return an error indicating which scope is required. + -1. Select the three dots next to the relevant Kinde management API, then choose **Manage scopes**. -2. Select the scopes you want to include in the token. For maximum security only enable the minimum scopes you require. 3. Select **Save**. -## Step 4: Get an access token and call the Kinde Management API +### 3. Get the test token + +1. Select **Kinde Management API** in the list of APIs. +2. Select **Test** in the menu. +3. Select the M2M application from the dropdown, and select **Get token**. +4. Now you can copy the test token for manual testing or select the **Use test token** button to open the management API page. + + ![kinde test token](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/321a49c0-f629-4c7a-9ef2-349ad0f31f00/public) + + + +### 4. Test endpoints in the Management API page + +1. Select **Use test token** button from the token page. The **Kinde Management API** page will open with the test token pre-populated. Here you can test the relevant endpoints. + + ![kinde management api page](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/72840d32-1f90-4fc3-30e9-40074f163f00/public) + +2. Search the endpoint you want to test (e.g., roles) +3. Select **Test request** in the code snippet. A pop-up will open. + + ![kinde management api test request](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/833a2c93-61ad-4fa7-8999-4b9ac4a44f00/public) + +4. Select **Send** and you will see the response JSON. -- Fast method: Generate a [test access token](/developer-tools/kinde-api/kinde-api-test-token/) in Kinde. - Other methods: Follow [this guide](/developer-tools/kinde-api/access-token-for-api/) that includes several different options for getting an access token, including via Postman. ## How M2M tokens are calculated in Kinde @@ -75,7 +102,3 @@ Where an access token is re-used - say where the same token is used to make anot Kinde’s free and Pro plans have a generous amount of M2M tokens included, before we start charging for them. For details, see our [pricing page](https://kinde.com/pricing/). -## Video demo: Get a test token for accessing the Kinde Management API - -Watch a video about how easy it is to test the Kinde Management API on our YouTube channel [here](https://www.youtube.com/watch?v=iqO7CL3QyY8). - From 71c6194ff6d67b1d6c424eda28dd53c7103130f4 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Thu, 30 Apr 2026 17:55:43 +0600 Subject: [PATCH 02/14] Reorganize the API pages --- .../kinde-api/about-m2m-scopes.mdx | 7 +- .../kinde-api/access-token-for-api.mdx | 149 +--- .../kinde-api/api-example-node.mdx | 5 +- .../kinde-api/api-rate-limits.mdx | 10 +- .../kinde-api/call-the-api-postman.mdx | 715 ++++++++++++++++++ .../kinde-api/connect-to-kinde-api.mdx | 17 +- .../kinde-api/kinde-api-test-token.mdx | 64 -- .../kinde-api/search-users-via-api.mdx | 6 +- .../kinde-api/troubleshoot-kinde-api.mdx | 5 +- 9 files changed, 754 insertions(+), 224 deletions(-) create mode 100644 src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx delete mode 100644 src/content/docs/developer-tools/kinde-api/kinde-api-test-token.mdx diff --git a/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx b/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx index 858d5152c..d81ca14ac 100644 --- a/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx +++ b/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx @@ -1,9 +1,10 @@ --- page_id: 6bf993fc-a195-4836-8eaf-133812be8876 -title: About scopes and Kinde API access -description: "Comprehensive guide to M2M scopes for Kinde API access, including scope examples and management procedures" +title: About scopes in Kinde Management API +description: "Comprehensive guide to M2M scopes for Kinde Management API, including scope examples and management procedures" sidebar: - order: 4 + order: 8 + label: "About scopes" relatedArticles: - 51899f7f-3436-46e0-9a1b-6ecc3603a0df - 50284476-2442-414c-af20-01ed3ef4ca4e diff --git a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx index 871eac64f..b05649ac1 100644 --- a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx @@ -3,6 +3,7 @@ page_id: fa5b704d-1682-47df-ac41-524b56096e79 title: Call the Kinde Management API sidebar: order: 2 + label: "Call the API - General Guide" relatedArticles: - 50284476-2442-414c-af20-01ed3ef4ca4e - 51899f7f-3436-46e0-9a1b-6ecc3603a0df @@ -39,28 +40,19 @@ deprecated: false ai_summary: Comprehensive guide to obtaining access tokens and calling the Kinde Management API using M2M applications and OAuth2 client credentials flow --- -Before you can get an access token and call the Kinde Management API, follow the steps to [create and authorize a machine-to-machine (M2M) application, with scopes](/developer-tools/kinde-api/connect-to-kinde-api/). +Learn how to call the Kinde Management API using client credentials. -## Get access token +### What you need -There are two main methods for getting an access token for the Kinde Management API. +- A Kinde M2M application with Management API access, appropriate scopes, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/#1-create-a-machine-to-machine-application) -### Method 1: Get a test access token in the Kinde Admin - -1. Open the M2M application you created for API access. -2. Go to **Test**. -3. Select **Get token**. -4. Select **Use test token**. You'll be taken to the API docs with the access token prepopulated. You can now test any endpoint. - -For full details, see [generate a test access token for the Kinde Management API](/developer-tools/kinde-api/kinde-api-test-token/). - -### Method 2: Perform a POST request to get an access token +## 1. Get an access token To ask Kinde for an access token for calling the management API, perform a POST request to the `https://.kinde.com/oauth2/token` endpoint, using the credentials of the M2M application you created in the prerequisite step. The payload should look as follows: - + @@ -338,11 +330,11 @@ The response will contain a signed JWT containing claims including the scopes th ``` -## Use the access token +## 2. Use the access token To use this token, include it in the Authorization header of your request. For example to get all users you would call: - + @@ -587,128 +579,3 @@ Make sure to replace `` with your Kinde subdomain and ` -2. Make sure you select `Save` or the variables will not persist. - -### Get the access token - -1. Go to **Collections**. Create a new collection called **Kinde**. -2. In the three dots menu next to the new **Kinde** folder, select **Add request**. - -Adding a request in Postman - -3. Go to the **Authorization** section and set the **Type** to **OAuth 2.0** and set the **Header Prefix** to **Bearer**. -4. In the **Configure New Token > Configuration options** section, set the **Grant Type** to **Client Credentials**. -5. Enter the **Access Token URL** using the domain variable you created above. For example, `{{business_domain}}/oauth2/token`. Note that even if you use a custom domain, the access token URL should still use your `https://.kinde.com` domain. - -Entering the access token URL - -6. Enter the **Client ID** and **Client Secret** using the environment variables you created earlier or by copying them from the Kinde application. -7. Set the **audience** to `{{business_domain}}/api`. To do this: - - Scroll down click **Advanced**. In the **Token request** section, select the `audience` key and enter the above URL in the **Value** field. Ensure it is being sent in the `body` of the request - - - -8. Go to the **Headers** tab. - -Setting the Content-Type value in Postman - -9. Select **Accept** and ensure the value is `application/json`. -10. In the **Authorization** section, select **Get New Access Token**. You should see a confirmation message. -11. Select **Proceed**. - -Access Token in Postman - -12. Select **Use Token**. You should now have the access token for making requests to the Kinde management API. See the [Kinde API documentation](/kinde-apis/management/) for all the available end points. - -### Test the API endpoints - -You can test your API access in Postman by sending a `GET` request to any Kinde API endpoint. See the [Kinde Management API library](/kinde-apis/management/) for options. - -Here’s an example using the `Get users` endpoint. - -1. Create a new `GET` request. -2. Enter a URL that contains the `/users` endpoint, e.g. `https://.kinde.com/api/v1/users` . - -Entering a Request URL in Postman - -3. Send the request. It should return your users in the body section. If it does, the connection is successful. - -Response body in Postman - -4. Repeat from step 1 for any other [Kinde API endpoints](/kinde-apis/management/) you want to test. diff --git a/src/content/docs/developer-tools/kinde-api/api-example-node.mdx b/src/content/docs/developer-tools/kinde-api/api-example-node.mdx index 774e0958b..24cf2bfd4 100644 --- a/src/content/docs/developer-tools/kinde-api/api-example-node.mdx +++ b/src/content/docs/developer-tools/kinde-api/api-example-node.mdx @@ -1,8 +1,9 @@ --- page_id: f99396dc-d158-4d37-a98b-386485b1ff69 -title: Call the Kinde API - NodeJS example +title: Call the Kinde Management API using NodeJS sidebar: - order: 6 + order: 4 + label: "Call the API - NodeJS" relatedArticles: - 6bf993fc-a195-4836-8eaf-133812be8876 - 51899f7f-3436-46e0-9a1b-6ecc3603a0df diff --git a/src/content/docs/developer-tools/kinde-api/api-rate-limits.mdx b/src/content/docs/developer-tools/kinde-api/api-rate-limits.mdx index 534d54f72..e5f3af14d 100644 --- a/src/content/docs/developer-tools/kinde-api/api-rate-limits.mdx +++ b/src/content/docs/developer-tools/kinde-api/api-rate-limits.mdx @@ -3,7 +3,7 @@ page_id: c944dcc9-35d1-4816-b2d3-a39fb0d3e68f title: API rate limits description: "Documentation on Kinde API rate limits, including rate and concurrency limiters, common causes, and graceful handling strategies" sidebar: - order: 7 + order: 9 relatedArticles: - 6bf993fc-a195-4836-8eaf-133812be8876 - 51899f7f-3436-46e0-9a1b-6ecc3603a0df @@ -66,3 +66,11 @@ Graceful handling involves monitoring for `429` status codes and triggering a re Your method should follow an exponential back-off schedule to reduce request volume as needed. We also recommend building randomness into the back-off schedule to avoid a ‘thundering herd’ effect. Another method is to manage traffic at a global level, and throttle it back if you detect substantial rate limiting. A common technique for controlling rate is to implement something like a token bucket rate limiting algorithm on the client-side. Ready-made and mature implementations for token bucket can be found in most programming languages. + +## How M2M tokens are calculated in Kinde + +An M2M token is generated each time you call the `/oauth2/token` Kinde API endpoint to retrieve an M2M access token. + +Where an access token is re-used - say where the same token is used to make another API request, this does not count as a new token. Similarly, where a token is re-used to make calls to other Kinde-registered APIs, this is also not counted as another token. + +Kinde’s free and Pro plans have a generous amount of M2M tokens included, before we start charging for them. For details, see our [pricing page](https://kinde.com/pricing/). \ No newline at end of file diff --git a/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx b/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx new file mode 100644 index 000000000..4b9d35432 --- /dev/null +++ b/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx @@ -0,0 +1,715 @@ +--- +page_id: cdb62fdc-cc83-4247-a0e0-7196bc7edb3e +title: Call the Kinde Management API with Postman +sidebar: + order: 3 + label: "Call the API - Postman" +relatedArticles: + - 50284476-2442-414c-af20-01ed3ef4ca4e + - 51899f7f-3436-46e0-9a1b-6ecc3603a0df + - 6bf993fc-a195-4836-8eaf-133812be8876 + - 601dd8c5-6ee1-474f-ad36-201e65280462 +app_context: + - m: settings + s: applications +topics: + - developer-tools + - kinde-api +sdk: [] +languages: + - csharp + - go + - java + - javascript + - objective-c + - php + - shell +audience: + - developers +complexity: intermediate +keywords: + - management api + - access token + - m2m application + - client credentials + - oauth2 + - api authentication +updated: 2024-01-15 +featured: false +deprecated: false +ai_summary: Comprehensive guide to obtaining access tokens and calling the Kinde Management API using M2M applications and OAuth2 client credentials flow +--- + +Before you can get an access token and call the Kinde Management API, follow the steps to [create and authorize a machine-to-machine (M2M) application, with scopes](/developer-tools/kinde-api/connect-to-kinde-api/). + +## Get access token + +There are two main methods for getting an access token for the Kinde Management API. + +### Method 1: Get a test access token in the Kinde Admin + +1. Open the M2M application you created for API access. +2. Go to **Test**. +3. Select **Get token**. +4. Select **Use test token**. You'll be taken to the API docs with the access token prepopulated. You can now test any endpoint. + +For full details, see [generate a test access token for the Kinde Management API](/developer-tools/kinde-api/kinde-api-test-token/). + +### Method 2: Perform a POST request to get an access token + +To ask Kinde for an access token for calling the management API, perform a POST request to the `https://.kinde.com/oauth2/token` endpoint, using the credentials of the M2M application you created in the prerequisite step. + +The payload should look as follows: + + + + + +```shellscript +curl --request POST \ + --url 'https://.kinde.com/oauth2/token' \ + --header 'content-type: application/x-www-form-urlencoded' \ + --data grant_type=client_credentials \ + --data 'client_id=' \ + --data 'client_secret=' \ + --data 'audience=https://.kinde.com/api' +``` + + + + + +```c# +var client = new RestClient("https://.kinde.com/oauth2/token"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/x-www-form-urlencoded"); +request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + + + + + +```go +package main + +import ( + "fmt + "strings + "net/http + "io/ioutil +) + +func main() { + + url := "https://.kinde.com/oauth2/token + + payload := strings.NewReader("grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi") + + req, _ := http.NewRequest("POST", url, payload) + + req.Header.Add("content-type", "application/x-www-form-urlencoded") + + res, _ := http.DefaultClient.Do(req) + + defer res.Body.Close() + body, _ := ioutil.ReadAll(res.Body) + + fmt.Println(res) + fmt.Println(string(body)) + +} +``` + + + + + +```java +HttpResponse response = Unirest.post("https://.kinde.com/oauth2/token") + .header("content-type", "application/x-www-form-urlencoded") + .body("grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi") + .asString(); +``` + + + + + +```js +async function getToken() { + try { + const response = await fetch(`https://.kinde.com/oauth2/token`, { + method: "POST", + headers: { + "content-type": "application/x-www-form-urlencoded" + }, + body: new URLSearchParams({ + audience: "https://.kinde.com/api", + grant_type: "client_credentials", + client_id: "", + client_secret: "" + }) + }); + + if (!response.ok) { + throw new Error(`Response status: ${response.status}`); + } + + const json = await response.json(); + console.log(json); + } catch (error) { + console.error(error.message); + } +} + +getToken(); +``` + + + + + +```objc +#import + +NSDictionary *headers = @{ @"content-type": @"application/x-www-form-urlencoded" }; + +NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"grant_type=client_credentials" dataUsingEncoding:NSUTF8StringEncoding]]; +[postData appendData:[@"&client_id=" dataUsingEncoding:NSUTF8StringEncoding]]; +[postData appendData:[@"&client_secret=" dataUsingEncoding:NSUTF8StringEncoding]]; +[postData appendData:[@"&audience=https://.kinde.com/api" dataUsingEncoding:NSUTF8StringEncoding]]; + +NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://.kinde.com/oauth2/token"] + cachePolicy:NSURLRequestUseProtocolCachePolicy + timeoutInterval:10.0]; +[request setHTTPMethod:@"POST"]; +[request setAllHTTPHeaderFields:headers]; +[request setHTTPBody:postData]; + +NSURLSession *session = [NSURLSession sharedSession]; +NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error) { + NSLog(@"%@", error); + } else { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; + NSLog(@"%@", httpResponse); + } + }]; +[dataTask resume]; +``` + + + + + +```php +$curl = curl_init(); + +curl_setopt_array($curl, [ + CURLOPT_URL => "https://.kinde.com/oauth2/token", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_POSTFIELDS => "grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi", + CURLOPT_HTTPHEADER => [ + "content-type: application/x-www-form-urlencoded + ], +]); + +$response = curl_exec($curl); +$err = curl_error($curl); + +curl_close($curl); + +if ($err) { + echo "cURL Error #:" . $err; +} else { + echo $response; +} +``` + + + + + +```python +import http.client + +conn = http.client.HTTPSConnection("") + +payload = "grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi + +headers = { 'content-type': "application/x-www-form-urlencoded" } + +conn.request("POST", "https://.kinde.com/oauth2/token", payload, headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +``` + + + + + +```ruby +require 'uri' +require 'net/http' +require 'openssl' + +url = URI("https://.kinde.com/oauth2/token") + +http = Net::HTTP.new(url.host, url.port) +http.use_ssl = true +http.verify_mode = OpenSSL::SSL::VERIFY_NONE + +request = Net::HTTP::Post.new(url) +request["content-type"] = 'application/x-www-form-urlencoded' +request.body = "grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi + +response = http.request(request) +puts response.read_body +``` + + + + + +```swift +import Foundation + +let headers = ["content-type": "application/x-www-form-urlencoded"] + +let postData = NSMutableData(data: "grant_type=client_credentials".data(using: String.Encoding.utf8)!) +postData.append("&client_id=".data(using: String.Encoding.utf8)!) +postData.append("&client_secret=".data(using: String.Encoding.utf8)!) +postData.append("&audience=https://.kinde.com/api".data(using: String.Encoding.utf8)!) + +let request = NSMutableURLRequest(url: NSURL(string: "https://.kinde.com/oauth2/token")! as URL, + cachePolicy: .useProtocolCachePolicy, + timeoutInterval: 10.0) +request.httpMethod = "POST +request.allHTTPHeaderFields = headers +request.httpBody = postData as Data + +let session = URLSession.shared +let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in + if (error != nil) { + print(error) + } else { + let httpResponse = response as? HTTPURLResponse + print(httpResponse) + } +}) + +dataTask.resume() +``` + + + + + +Make sure to replace ``, `` and `` with your own details. + +The response will contain a signed JWT containing claims including the scopes the token is allowed to access and the expiry time. Here is an example token: + +```json + +{ + "aud": [ + "https://example.kinde.com/api + ], + "azp": "bd69bb9fe5db44a38b6b2dacd1f4b451", + "exp": 1729812040, + "gty": [ + "client_credentials + ], + "iat": 1729725640, + "iss": "https://example.kinde.com", + "jti": "6f091ebe-44ba-4afc-bd2f-05fcccafc89e", + "scope": "read:users update:users" +} + +``` + +## Use the access token + +To use this token, include it in the Authorization header of your request. For example to get all users you would call: + + + + + +```shellscript +curl --request GET \ + --url 'https://.kinde.com/api/v1/users' \ + --header 'authorization: Bearer ' \ + --header 'content-type: application/json' +``` + + + + + +```c# +var client = new RestClient("https://.kinde.com/api/v1/users"); +var request = new RestRequest(Method.GET); +request.AddHeader("content-type", "application/json"); +request.AddHeader("authorization", "Bearer "); +IRestResponse response = client.Execute(request); +``` + + + + + +```go +package main + +import ( + "fmt + "net/http + "io/ioutil +) + +func main() { + + url := "https://.kinde.com/api/v1/users + + req, _ := http.NewRequest("GET", url, nil) + + req.Header.Add("content-type", "application/json") + req.Header.Add("authorization", "Bearer ") + + res, _ := http.DefaultClient.Do(req) + + defer res.Body.Close() + body, _ := ioutil.ReadAll(res.Body) + + fmt.Println(res) + fmt.Println(string(body)) + +} +``` + + + + + +```java +HttpResponse response = Unirest.get("https://.kinde.com/api/v1/users") + .header("content-type", "application/json") + .header("authorization", "Bearer ") + .asString(); +``` + + + + + +```js +async function getUsers() { + try { + const response = await fetch(`https://.kinde.com/api/v1/users`, { + method: "GET", + headers: { + "content-type": "application/json", + authorization: "Bearer " + } + }); + + if (!response.ok) { + throw new Error(`Response status: ${response.status}`); + } + + const json = await response.json(); + console.log(json); + } catch (error) { + console.error(error.message); + } +} + +getUsers(); +``` + + + + + +```objc +#import + +NSDictionary *headers = @{ @"content-type": @"application/json", + @"authorization": @"Bearer " }; + +NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://.kinde.com/api/v1/users"] + cachePolicy:NSURLRequestUseProtocolCachePolicy + timeoutInterval:10.0]; +[request setHTTPMethod:@"GET"]; +[request setAllHTTPHeaderFields:headers]; + +NSURLSession *session = [NSURLSession sharedSession]; +NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error) { + NSLog(@"%@", error); + } else { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; + NSLog(@"%@", httpResponse); + } + }]; +[dataTask resume]; +``` + + + + + +```php +$curl = curl_init(); + +curl_setopt_array($curl, [ + CURLOPT_URL => "https://.kinde.com/api/v1/users", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_HTTPHEADER => [ + "authorization: Bearer ", + "content-type: application/json + ], +]); + +$response = curl_exec($curl); +$err = curl_error($curl); + +curl_close($curl); + +if ($err) { + echo "cURL Error #:" . $err; +} else { + echo $response; +} +``` + + + + + +```python +import http.client + +conn = http.client.HTTPSConnection("") + +headers = { + 'content-type': "application/json", + 'authorization': "Bearer " + } + +conn.request("GET", "https://.kinde.com/api/v1/users", headers=headers) + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) +``` + + + + + +```ruby +require 'uri' +require 'net/http' +require 'openssl' + +url = URI("https://.kinde.com/api/v1/users") + +http = Net::HTTP.new(url.host, url.port) +http.use_ssl = true +http.verify_mode = OpenSSL::SSL::VERIFY_NONE + +request = Net::HTTP::Get.new(url) +request["content-type"] = 'application/json' +request["authorization"] = 'Bearer ' + +response = http.request(request) +puts response.read_body +``` + + + + + +```swift +import Foundation + +let headers = [ + "content-type": "application/json", + "authorization": "Bearer " +] + +let request = NSMutableURLRequest(url: NSURL(string: "https://.kinde.com/api/v1/users")! as URL, + cachePolicy: .useProtocolCachePolicy, + timeoutInterval: 10.0) +request.httpMethod = "GET +request.allHTTPHeaderFields = headers + +let session = URLSession.shared +let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in + if (error != nil) { + print(error) + } else { + let httpResponse = response as? HTTPURLResponse + print(httpResponse) + } +}) + +dataTask.resume() +``` + + + + + +Make sure to replace `` with your Kinde subdomain and `` with the token received in the previous step. + +## Use the Kinde Management API JS SDK + +As an alternative to making HTTP calls, you can also use the [Kinde Management API JS](https://github.com/kinde-oss/management-api-js/) SDK. + +You can use it to automatically obtain tokens for, and interact with the Kinde management API. + +## Alternative - using Postman guide + +### Set up Postman environment + +We recommend you do this in a non-production environment first. + +If you decide to use Postman, we recommend that you set up a Postman environment. Here's some [troubleshooting solutions](/developer-tools/kinde-api/troubleshoot-kinde-api/) in case you need them. + +1. Add your Kinde machine to machine application keys as environment variables. + +Adding environment variables in Postman +2. Make sure you select `Save` or the variables will not persist. + +### Get the access token + +1. Go to **Collections**. Create a new collection called **Kinde**. +2. In the three dots menu next to the new **Kinde** folder, select **Add request**. + +Adding a request in Postman + +3. Go to the **Authorization** section and set the **Type** to **OAuth 2.0** and set the **Header Prefix** to **Bearer**. +4. In the **Configure New Token > Configuration options** section, set the **Grant Type** to **Client Credentials**. +5. Enter the **Access Token URL** using the domain variable you created above. For example, `{{business_domain}}/oauth2/token`. Note that even if you use a custom domain, the access token URL should still use your `https://.kinde.com` domain. + +Entering the access token URL + +6. Enter the **Client ID** and **Client Secret** using the environment variables you created earlier or by copying them from the Kinde application. +7. Set the **audience** to `{{business_domain}}/api`. To do this: + - Scroll down click **Advanced**. In the **Token request** section, select the `audience` key and enter the above URL in the **Value** field. Ensure it is being sent in the `body` of the request + + + +8. Go to the **Headers** tab. + +Setting the Content-Type value in Postman + +9. Select **Accept** and ensure the value is `application/json`. +10. In the **Authorization** section, select **Get New Access Token**. You should see a confirmation message. +11. Select **Proceed**. + +Access Token in Postman + +12. Select **Use Token**. You should now have the access token for making requests to the Kinde management API. See the [Kinde API documentation](/kinde-apis/management/) for all the available end points. + +### Test the API endpoints + +You can test your API access in Postman by sending a `GET` request to any Kinde API endpoint. See the [Kinde Management API library](/kinde-apis/management/) for options. + +Here’s an example using the `Get users` endpoint. + +1. Create a new `GET` request. +2. Enter a URL that contains the `/users` endpoint, e.g. `https://.kinde.com/api/v1/users` . + +Entering a Request URL in Postman + +3. Send the request. It should return your users in the body section. If it does, the connection is successful. + +Response body in Postman + +4. Repeat from step 1 for any other [Kinde API endpoints](/kinde-apis/management/) you want to test. diff --git a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx index d8918cbc0..5d9bf973b 100644 --- a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx @@ -4,7 +4,7 @@ title: Kinde Management API Quickstart Guide description: "Step-by-step guide to setting up M2M applications and authorizing them for Kinde Management API access with proper scopes" sidebar: order: 1 - label: "Kinde Management API Quickstart" + label: "Quickstart" tableOfContents: maxHeadingLevel: 3 relatedArticles: @@ -52,6 +52,13 @@ This guide shows you how to set up a new machine to machine (M2M) application, a 1. Go to your Kinde dashboard and select **Add application**. 3. Give the application a name (e.g., "API Automation"), and select **Machine to Machine** as the application type. 4. Select **Save**. +5. Go to the **Details** page and copy the app keys: + + - Domain + - Client ID + - Client Secret + + You will need these details when you call the Kinde Management API. ### 2. Authorize and add scopes @@ -94,11 +101,3 @@ This guide shows you how to set up a new machine to machine (M2M) application, a - Other methods: Follow [this guide](/developer-tools/kinde-api/access-token-for-api/) that includes several different options for getting an access token, including via Postman. -## How M2M tokens are calculated in Kinde - -An M2M token is generated each time you call the `/oauth2/token` Kinde API endpoint to retrieve an M2M access token. - -Where an access token is re-used - say where the same token is used to make another API request, this does not count as a new token. Similarly, where a token is re-used to make calls to other Kinde-registered APIs, this is also not counted as another token. - -Kinde’s free and Pro plans have a generous amount of M2M tokens included, before we start charging for them. For details, see our [pricing page](https://kinde.com/pricing/). - diff --git a/src/content/docs/developer-tools/kinde-api/kinde-api-test-token.mdx b/src/content/docs/developer-tools/kinde-api/kinde-api-test-token.mdx deleted file mode 100644 index 889ddd0fd..000000000 --- a/src/content/docs/developer-tools/kinde-api/kinde-api-test-token.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -page_id: 0758f690-fe6f-4086-90fb-59a0db435e79 -title: Get token to test the Kinde Management API -description: "Guide to generating test tokens for the Kinde Management API using the Kinde admin interface for quick testing" -sidebar: - order: 3 -relatedArticles: - - 50284476-2442-414c-af20-01ed3ef4ca4e - - 51899f7f-3436-46e0-9a1b-6ecc3603a0df - - 6bf993fc-a195-4836-8eaf-133812be8876 - - 601dd8c5-6ee1-474f-ad36-201e65280462 -topics: - - developer-tools - - kinde-api -sdk: [] -languages: [] -audience: - - developers -complexity: beginner -keywords: - - test token - - management api - - m2m application - - api testing - - token generation -updated: 2024-01-15 -featured: false -deprecated: false -ai_summary: Guide to generating test tokens for the Kinde Management API using the Kinde admin interface for quick testing ---- - -Kinde lets you quickly generate a test token for testing the Kinde Management API with your M2M application. This can save you time generating a token via Postman or other service. - -This process assumes you have [set up access to the Kinde Management API](/developer-tools/kinde-api/connect-to-kinde-api/). - -1. In Kinde, go to **Settings > APIs**. -2. Select **View details** on the Kinde Management API. -3. Select **Test** in the menu. -4. Select the authorized M2M application, then select **Get token**. Token details are generated. - - ![shows the generated token for copying and using](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/321a49c0-f629-4c7a-9ef2-349ad0f31f00/public) - -5. Copy the code and use it to test. -6. Or, select **Use test token.** The Kinde Management API docs opens with the test token pre-populated. - - ![Shows Kinde Management API page showing test token in use](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/72840d32-1f90-4fc3-30e9-40074f163f00/public) - - - Search for the endpoint you want to test. - - Select **Test request** in the code snippet. - - ![Shows API code snippet and test request button](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/833a2c93-61ad-4fa7-8999-4b9ac4a44f00/public) - - - The test will complete using the test token you generated. - - - - - - - - - - - diff --git a/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx b/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx index 6e14a8839..cd9f80820 100644 --- a/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx @@ -1,9 +1,10 @@ --- page_id: 19b5cea3-bfce-4fe9-94ac-ddd8b872af3e -title: Search users via the Kinde API +title: Tutorial - Search users via the Kinde Management API description: "Guide to searching and filtering users via the Kinde Management API using query parameters and property filters" sidebar: - order: 8 + order: 7 + label: "Tutorial - Search users" tableOfContents: maxHeadingLevel: 3 relatedArticles: @@ -34,6 +35,7 @@ ai_summary: Guide to searching and filtering users via the Kinde Management API You can search users and filter results via the Kinde Management API. You might need to do this to isolate users with specific properties defined, for example, to find users in a particular city. + ## Make an API search request Search with `GET` request: `/api/v1/search/users?query=searchterm` diff --git a/src/content/docs/developer-tools/kinde-api/troubleshoot-kinde-api.mdx b/src/content/docs/developer-tools/kinde-api/troubleshoot-kinde-api.mdx index b5123476b..22d2ca95b 100644 --- a/src/content/docs/developer-tools/kinde-api/troubleshoot-kinde-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/troubleshoot-kinde-api.mdx @@ -1,9 +1,10 @@ --- page_id: 601dd8c5-6ee1-474f-ad36-201e65280462 -title: Troubleshooting Kinde API access +title: Troubleshooting Kinde Management API description: "Troubleshooting guide for common Kinde API issues including null responses and scope errors" sidebar: - order: 5 + order: 10 + label: "Troubleshooting" relatedArticles: - 51899f7f-3436-46e0-9a1b-6ecc3603a0df - 6bf993fc-a195-4836-8eaf-133812be8876 From 9028f6fc86a622f0af8793604fc29d5a6bae1c90 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Thu, 30 Apr 2026 19:37:59 +0600 Subject: [PATCH 03/14] update the docs with steps --- .../kinde-api/access-token-for-api.mdx | 27 +- .../kinde-api/api-example-node.mdx | 69 +- .../kinde-api/call-the-api-postman.mdx | 715 +++--------------- .../kinde-api/connect-to-kinde-api.mdx | 51 +- 4 files changed, 191 insertions(+), 671 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx index b05649ac1..63ad84fca 100644 --- a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx @@ -4,6 +4,8 @@ title: Call the Kinde Management API sidebar: order: 2 label: "Call the API - General Guide" +tableOfContents: + maxHeadingLevel: 3 relatedArticles: - 50284476-2442-414c-af20-01ed3ef4ca4e - 51899f7f-3436-46e0-9a1b-6ecc3603a0df @@ -37,20 +39,23 @@ keywords: updated: 2024-01-15 featured: false deprecated: false -ai_summary: Comprehensive guide to obtaining access tokens and calling the Kinde Management API using M2M applications and OAuth2 client credentials flow +ai_summary: "Comprehensive guide to obtaining access tokens and calling the Kinde Management API using M2M applications and OAuth2 client credentials flow" --- Learn how to call the Kinde Management API using client credentials. ### What you need -- A Kinde M2M application with Management API access, appropriate scopes, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/#1-create-a-machine-to-machine-application) +- A Kinde M2M application with Management API access, appropriate scopes, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) -## 1. Get an access token +## Call the API -To ask Kinde for an access token for calling the management API, perform a POST request to the `https://.kinde.com/oauth2/token` endpoint, using the credentials of the M2M application you created in the prerequisite step. +### 1. Get an access token -The payload should look as follows: +1. Get the app keys for your M2M application (Domain, Client ID, and Client Secret). +2. Make a POST request to the `https://.kinde.com/oauth2/token` endpoint using your prefered programming language below: + + Make sure to replace ``, `` and `` with your own details. @@ -307,12 +312,9 @@ dataTask.resume() -Make sure to replace ``, `` and `` with your own details. - -The response will contain a signed JWT containing claims including the scopes the token is allowed to access and the expiry time. Here is an example token: +3. You will get a response with an access token. The response will contain a signed JWT containing claims including the scopes the token is allowed to access and the expiry time. Here is an example of a decoded access token: ```json - { "aud": [ "https://example.kinde.com/api @@ -327,12 +329,11 @@ The response will contain a signed JWT containing claims including the scopes th "jti": "6f091ebe-44ba-4afc-bd2f-05fcccafc89e", "scope": "read:users update:users" } - ``` -## 2. Use the access token +### 2. Use the access token -To use this token, include it in the Authorization header of your request. For example to get all users you would call: +1. Include the access token in the Authorization header of your request. For example to get all users you would call: @@ -572,7 +573,7 @@ dataTask.resume() -Make sure to replace `` with your Kinde subdomain and `` with the token received in the previous step. +2. You will get the appropriate response from the Management API. ## Use the Kinde Management API JS SDK diff --git a/src/content/docs/developer-tools/kinde-api/api-example-node.mdx b/src/content/docs/developer-tools/kinde-api/api-example-node.mdx index 24cf2bfd4..2f6ab890f 100644 --- a/src/content/docs/developer-tools/kinde-api/api-example-node.mdx +++ b/src/content/docs/developer-tools/kinde-api/api-example-node.mdx @@ -1,9 +1,11 @@ --- page_id: f99396dc-d158-4d37-a98b-386485b1ff69 -title: Call the Kinde Management API using NodeJS +title: Call the Kinde Management API using Node.js sidebar: order: 4 - label: "Call the API - NodeJS" + label: "Call the API - Node.js" +tableOfContents: + maxHeadingLevel: 3 relatedArticles: - 6bf993fc-a195-4836-8eaf-133812be8876 - 51899f7f-3436-46e0-9a1b-6ecc3603a0df @@ -31,18 +33,29 @@ deprecated: false ai_summary: NodeJS example demonstrating how to obtain access tokens and call the Kinde Management API using fetch and OAuth2 client credentials --- -If you don’t use Postman or other similar tools to test your connections, here’s an example of how to call the [Kinde Management API](/kinde-apis/management/) in NodeJS. +Learn how to call the Kinde Management API using Node.js. -1. [Add a machine to machine application](/developer-tools/kinde-api/connect-to-kinde-api/) for API access, and copy the **App keys - Domain, Client ID** and **Client secret** from the application. -2. Call the Kinde token endpoint using the app key details you copied at step 1. Here’s a code sample in NodeJS. This should return an access token. +### What you need - ```jsx +- A Kinde M2M application with Management API access, appropriate scopes, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) +- [Node.js](https://nodejs.org/) version 20+ installed on your machine + +## Call the API + +### 1. Get an access token + +1. Get the app keys for your M2M application (Domain, Client ID, and Client Secret). +2. Make a POST request to the `https://.kinde.com/oauth2/token` endpoint using the following code sample: + + Make sure to replace ``, `` and `` with your own details. + + ```javascript const getAccessToken = async () => { try { const searchParams = { grant_type: "client_credentials", - client_id: "", - client_secret: "", + client_id: "", + client_secret: "", audience: "https://.kinde.com/api" }; @@ -59,11 +72,43 @@ If you don’t use Postman or other similar tools to test your connections, here console.error(err); } }; + + await getAccessToken(); ``` +3. You will get a response with an access token. The response will contain a signed JWT containing claims including the scopes the token is allowed to access and the expiry time. -3. Use the access token to call the Kinde management API. Here’s an example of calling the `users` endpoint in NodeJS: + ```json + { + "access_token": "...", + "token_type": "Bearer", + "expires_in": 3600 + } + ``` - ```jsx +Here is an example of a decoded access token: + + ```json + { + "aud": [ + "https://example.kinde.com/api + ], + "azp": "bd69bb9fe5db44a38b6b2dacd1f4b451", + "exp": 1729812040, + "gty": [ + "client_credentials + ], + "iat": 1729725640, + "iss": "https://example.kinde.com", + "jti": "6f091ebe-44ba-4afc-bd2f-05fcccafc89e", + "scope": "read:users update:users" + } + ``` + +### 2. Use the access token + +1. Use the access token to call the Kinde management API: + + ```javascript const getUsers = async () => { const accessToken = await getAccessToken(); @@ -84,4 +129,6 @@ If you don’t use Postman or other similar tools to test your connections, here }; ``` -4. Dive into our [API docs](/kinde-apis/management/) and starting connecting your product to ours. +2. You will get the appropriate response from the Management API. + +3. Repeat the steps for any other [Kinde API endpoints](/kinde-apis/management/) you want to test. \ No newline at end of file diff --git a/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx b/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx index 4b9d35432..24e12c57a 100644 --- a/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx +++ b/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx @@ -4,6 +4,8 @@ title: Call the Kinde Management API with Postman sidebar: order: 3 label: "Call the API - Postman" +tableOfContents: + maxHeadingLevel: 3 relatedArticles: - 50284476-2442-414c-af20-01ed3ef4ca4e - 51899f7f-3436-46e0-9a1b-6ecc3603a0df @@ -40,648 +42,105 @@ deprecated: false ai_summary: Comprehensive guide to obtaining access tokens and calling the Kinde Management API using M2M applications and OAuth2 client credentials flow --- -Before you can get an access token and call the Kinde Management API, follow the steps to [create and authorize a machine-to-machine (M2M) application, with scopes](/developer-tools/kinde-api/connect-to-kinde-api/). +Learn how to call the Kinde Management API using Postman. -## Get access token +### What you need -There are two main methods for getting an access token for the Kinde Management API. +- A Kinde M2M application with Management API access, appropriate scopes, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) +- A [Postman client](https://www.postman.com/) installed on your machine -### Method 1: Get a test access token in the Kinde Admin +## Postman guide -1. Open the M2M application you created for API access. -2. Go to **Test**. -3. Select **Get token**. -4. Select **Use test token**. You'll be taken to the API docs with the access token prepopulated. You can now test any endpoint. +### 1. Set up Postman environment -For full details, see [generate a test access token for the Kinde Management API](/developer-tools/kinde-api/kinde-api-test-token/). - -### Method 2: Perform a POST request to get an access token - -To ask Kinde for an access token for calling the management API, perform a POST request to the `https://.kinde.com/oauth2/token` endpoint, using the credentials of the M2M application you created in the prerequisite step. - -The payload should look as follows: - - - - - -```shellscript -curl --request POST \ - --url 'https://.kinde.com/oauth2/token' \ - --header 'content-type: application/x-www-form-urlencoded' \ - --data grant_type=client_credentials \ - --data 'client_id=' \ - --data 'client_secret=' \ - --data 'audience=https://.kinde.com/api' -``` - - - - - -```c# -var client = new RestClient("https://.kinde.com/oauth2/token"); -var request = new RestRequest(Method.POST); -request.AddHeader("content-type", "application/x-www-form-urlencoded"); -request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); -``` - - - - - -```go -package main - -import ( - "fmt - "strings - "net/http - "io/ioutil -) - -func main() { - - url := "https://.kinde.com/oauth2/token - - payload := strings.NewReader("grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi") - - req, _ := http.NewRequest("POST", url, payload) - - req.Header.Add("content-type", "application/x-www-form-urlencoded") - - res, _ := http.DefaultClient.Do(req) - - defer res.Body.Close() - body, _ := ioutil.ReadAll(res.Body) - - fmt.Println(res) - fmt.Println(string(body)) - -} -``` - - - - - -```java -HttpResponse response = Unirest.post("https://.kinde.com/oauth2/token") - .header("content-type", "application/x-www-form-urlencoded") - .body("grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi") - .asString(); -``` - - - - - -```js -async function getToken() { - try { - const response = await fetch(`https://.kinde.com/oauth2/token`, { - method: "POST", - headers: { - "content-type": "application/x-www-form-urlencoded" - }, - body: new URLSearchParams({ - audience: "https://.kinde.com/api", - grant_type: "client_credentials", - client_id: "", - client_secret: "" - }) - }); - - if (!response.ok) { - throw new Error(`Response status: ${response.status}`); - } - - const json = await response.json(); - console.log(json); - } catch (error) { - console.error(error.message); - } -} - -getToken(); -``` - - - - - -```objc -#import - -NSDictionary *headers = @{ @"content-type": @"application/x-www-form-urlencoded" }; - -NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"grant_type=client_credentials" dataUsingEncoding:NSUTF8StringEncoding]]; -[postData appendData:[@"&client_id=" dataUsingEncoding:NSUTF8StringEncoding]]; -[postData appendData:[@"&client_secret=" dataUsingEncoding:NSUTF8StringEncoding]]; -[postData appendData:[@"&audience=https://.kinde.com/api" dataUsingEncoding:NSUTF8StringEncoding]]; - -NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://.kinde.com/oauth2/token"] - cachePolicy:NSURLRequestUseProtocolCachePolicy - timeoutInterval:10.0]; -[request setHTTPMethod:@"POST"]; -[request setAllHTTPHeaderFields:headers]; -[request setHTTPBody:postData]; - -NSURLSession *session = [NSURLSession sharedSession]; -NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request - completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - if (error) { - NSLog(@"%@", error); - } else { - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; - NSLog(@"%@", httpResponse); - } - }]; -[dataTask resume]; -``` - - - - - -```php -$curl = curl_init(); - -curl_setopt_array($curl, [ - CURLOPT_URL => "https://.kinde.com/oauth2/token", - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi", - CURLOPT_HTTPHEADER => [ - "content-type: application/x-www-form-urlencoded - ], -]); - -$response = curl_exec($curl); -$err = curl_error($curl); - -curl_close($curl); - -if ($err) { - echo "cURL Error #:" . $err; -} else { - echo $response; -} -``` - - - - - -```python -import http.client - -conn = http.client.HTTPSConnection("") - -payload = "grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi - -headers = { 'content-type': "application/x-www-form-urlencoded" } - -conn.request("POST", "https://.kinde.com/oauth2/token", payload, headers) - -res = conn.getresponse() -data = res.read() - -print(data.decode("utf-8")) -``` - - - - - -```ruby -require 'uri' -require 'net/http' -require 'openssl' - -url = URI("https://.kinde.com/oauth2/token") - -http = Net::HTTP.new(url.host, url.port) -http.use_ssl = true -http.verify_mode = OpenSSL::SSL::VERIFY_NONE - -request = Net::HTTP::Post.new(url) -request["content-type"] = 'application/x-www-form-urlencoded' -request.body = "grant_type=client_credentials&client_id=&client_secret=&audience=https%3A%2F%2F.kinde.com%2Fapi - -response = http.request(request) -puts response.read_body -``` - - - - - -```swift -import Foundation - -let headers = ["content-type": "application/x-www-form-urlencoded"] - -let postData = NSMutableData(data: "grant_type=client_credentials".data(using: String.Encoding.utf8)!) -postData.append("&client_id=".data(using: String.Encoding.utf8)!) -postData.append("&client_secret=".data(using: String.Encoding.utf8)!) -postData.append("&audience=https://.kinde.com/api".data(using: String.Encoding.utf8)!) - -let request = NSMutableURLRequest(url: NSURL(string: "https://.kinde.com/oauth2/token")! as URL, - cachePolicy: .useProtocolCachePolicy, - timeoutInterval: 10.0) -request.httpMethod = "POST -request.allHTTPHeaderFields = headers -request.httpBody = postData as Data - -let session = URLSession.shared -let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in - if (error != nil) { - print(error) - } else { - let httpResponse = response as? HTTPURLResponse - print(httpResponse) - } -}) - -dataTask.resume() -``` - - - - - -Make sure to replace ``, `` and `` with your own details. - -The response will contain a signed JWT containing claims including the scopes the token is allowed to access and the expiry time. Here is an example token: - -```json - -{ - "aud": [ - "https://example.kinde.com/api - ], - "azp": "bd69bb9fe5db44a38b6b2dacd1f4b451", - "exp": 1729812040, - "gty": [ - "client_credentials - ], - "iat": 1729725640, - "iss": "https://example.kinde.com", - "jti": "6f091ebe-44ba-4afc-bd2f-05fcccafc89e", - "scope": "read:users update:users" -} - -``` - -## Use the access token - -To use this token, include it in the Authorization header of your request. For example to get all users you would call: - - - - - -```shellscript -curl --request GET \ - --url 'https://.kinde.com/api/v1/users' \ - --header 'authorization: Bearer ' \ - --header 'content-type: application/json' -``` - - - - - -```c# -var client = new RestClient("https://.kinde.com/api/v1/users"); -var request = new RestRequest(Method.GET); -request.AddHeader("content-type", "application/json"); -request.AddHeader("authorization", "Bearer "); -IRestResponse response = client.Execute(request); -``` - - - - - -```go -package main - -import ( - "fmt - "net/http - "io/ioutil -) - -func main() { - - url := "https://.kinde.com/api/v1/users - - req, _ := http.NewRequest("GET", url, nil) - - req.Header.Add("content-type", "application/json") - req.Header.Add("authorization", "Bearer ") - - res, _ := http.DefaultClient.Do(req) - - defer res.Body.Close() - body, _ := ioutil.ReadAll(res.Body) - - fmt.Println(res) - fmt.Println(string(body)) - -} -``` - - - - - -```java -HttpResponse response = Unirest.get("https://.kinde.com/api/v1/users") - .header("content-type", "application/json") - .header("authorization", "Bearer ") - .asString(); -``` - - - - - -```js -async function getUsers() { - try { - const response = await fetch(`https://.kinde.com/api/v1/users`, { - method: "GET", - headers: { - "content-type": "application/json", - authorization: "Bearer " - } - }); - - if (!response.ok) { - throw new Error(`Response status: ${response.status}`); - } - - const json = await response.json(); - console.log(json); - } catch (error) { - console.error(error.message); - } -} - -getUsers(); -``` - - - - - -```objc -#import - -NSDictionary *headers = @{ @"content-type": @"application/json", - @"authorization": @"Bearer " }; - -NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://.kinde.com/api/v1/users"] - cachePolicy:NSURLRequestUseProtocolCachePolicy - timeoutInterval:10.0]; -[request setHTTPMethod:@"GET"]; -[request setAllHTTPHeaderFields:headers]; - -NSURLSession *session = [NSURLSession sharedSession]; -NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request - completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - if (error) { - NSLog(@"%@", error); - } else { - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; - NSLog(@"%@", httpResponse); - } - }]; -[dataTask resume]; -``` - - - - - -```php -$curl = curl_init(); - -curl_setopt_array($curl, [ - CURLOPT_URL => "https://.kinde.com/api/v1/users", - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", - CURLOPT_HTTPHEADER => [ - "authorization: Bearer ", - "content-type: application/json - ], -]); - -$response = curl_exec($curl); -$err = curl_error($curl); - -curl_close($curl); - -if ($err) { - echo "cURL Error #:" . $err; -} else { - echo $response; -} -``` - - - - - -```python -import http.client - -conn = http.client.HTTPSConnection("") - -headers = { - 'content-type': "application/json", - 'authorization': "Bearer " - } - -conn.request("GET", "https://.kinde.com/api/v1/users", headers=headers) - -res = conn.getresponse() -data = res.read() - -print(data.decode("utf-8")) -``` - - - - - -```ruby -require 'uri' -require 'net/http' -require 'openssl' - -url = URI("https://.kinde.com/api/v1/users") - -http = Net::HTTP.new(url.host, url.port) -http.use_ssl = true -http.verify_mode = OpenSSL::SSL::VERIFY_NONE - -request = Net::HTTP::Get.new(url) -request["content-type"] = 'application/json' -request["authorization"] = 'Bearer ' - -response = http.request(request) -puts response.read_body -``` - - - - - -```swift -import Foundation - -let headers = [ - "content-type": "application/json", - "authorization": "Bearer " -] - -let request = NSMutableURLRequest(url: NSURL(string: "https://.kinde.com/api/v1/users")! as URL, - cachePolicy: .useProtocolCachePolicy, - timeoutInterval: 10.0) -request.httpMethod = "GET -request.allHTTPHeaderFields = headers - -let session = URLSession.shared -let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in - if (error != nil) { - print(error) - } else { - let httpResponse = response as? HTTPURLResponse - print(httpResponse) - } -}) - -dataTask.resume() -``` - - - - - -Make sure to replace `` with your Kinde subdomain and `` with the token received in the previous step. - -## Use the Kinde Management API JS SDK - -As an alternative to making HTTP calls, you can also use the [Kinde Management API JS](https://github.com/kinde-oss/management-api-js/) SDK. - -You can use it to automatically obtain tokens for, and interact with the Kinde management API. - -## Alternative - using Postman guide - -### Set up Postman environment - -We recommend you do this in a non-production environment first. - -If you decide to use Postman, we recommend that you set up a Postman environment. Here's some [troubleshooting solutions](/developer-tools/kinde-api/troubleshoot-kinde-api/) in case you need them. +We recommend that you set up a Postman environment and test this in a non-production environment first. Here's some [troubleshooting solutions](/developer-tools/kinde-api/troubleshoot-kinde-api/) in case you need them. 1. Add your Kinde machine to machine application keys as environment variables. -Adding environment variables in Postman -2. Make sure you select `Save` or the variables will not persist. + Adding environment variables in Postman -### Get the access token +2. Select **Save** for the variables to persist. + +### 2. Get the access token 1. Go to **Collections**. Create a new collection called **Kinde**. 2. In the three dots menu next to the new **Kinde** folder, select **Add request**. -Adding a request in Postman + Adding a request in Postman 3. Go to the **Authorization** section and set the **Type** to **OAuth 2.0** and set the **Header Prefix** to **Bearer**. 4. In the **Configure New Token > Configuration options** section, set the **Grant Type** to **Client Credentials**. 5. Enter the **Access Token URL** using the domain variable you created above. For example, `{{business_domain}}/oauth2/token`. Note that even if you use a custom domain, the access token URL should still use your `https://.kinde.com` domain. -Entering the access token URL + Entering the access token URL 6. Enter the **Client ID** and **Client Secret** using the environment variables you created earlier or by copying them from the Kinde application. 7. Set the **audience** to `{{business_domain}}/api`. To do this: - Scroll down click **Advanced**. In the **Token request** section, select the `audience` key and enter the above URL in the **Value** field. Ensure it is being sent in the `body` of the request - + 8. Go to the **Headers** tab. -Setting the Content-Type value in Postman + Setting the Content-Type value in Postman 9. Select **Accept** and ensure the value is `application/json`. 10. In the **Authorization** section, select **Get New Access Token**. You should see a confirmation message. 11. Select **Proceed**. -Access Token in Postman + Access Token in Postman 12. Select **Use Token**. You should now have the access token for making requests to the Kinde management API. See the [Kinde API documentation](/kinde-apis/management/) for all the available end points. -### Test the API endpoints +### 3. Test the API endpoints You can test your API access in Postman by sending a `GET` request to any Kinde API endpoint. See the [Kinde Management API library](/kinde-apis/management/) for options. @@ -690,26 +149,26 @@ Here’s an example using the `Get users` endpoint. 1. Create a new `GET` request. 2. Enter a URL that contains the `/users` endpoint, e.g. `https://.kinde.com/api/v1/users` . -Entering a Request URL in Postman + Entering a Request URL in Postman 3. Send the request. It should return your users in the body section. If it does, the connection is successful. -Response body in Postman - -4. Repeat from step 1 for any other [Kinde API endpoints](/kinde-apis/management/) you want to test. + Response body in Postman + +4. Repeat from step 1 for any other [Kinde API endpoints](/kinde-apis/management/) you want to test. \ No newline at end of file diff --git a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx index 5d9bf973b..b83d2f6d7 100644 --- a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx @@ -39,33 +39,29 @@ ai_summary: Step-by-step guide to setting up M2M applications and authorizing th The Kinde Management API let's you do everything you can do with the Kinde UI. It is useful for pragmatically managing your Kinde account and resources such as use in CI/CD pipelines. -In order to call the Kinde Management API, you will need a Kinde management API access token. These tokens are generated by using an authorized M2M application to call the Kinde token endpoint. +In order to call the Kinde Management API, you will need a **Machine to Machine (M2M)** access token authorized to use the Management API. -This guide shows you how to set up a new machine to machine (M2M) application, and authorize it for Kinde Management API access. +This guide shows you how to set up and authorize a new M2M application with the appropriate scopes. Take a look at this [YouTube video](https://www.youtube.com/watch?v=iqO7CL3QyY8) for a quick demo: ## Quickstart guide -### 1. Create a machine to machine application +### 1. Create a M2M application 1. Go to your Kinde dashboard and select **Add application**. 3. Give the application a name (e.g., "API Automation"), and select **Machine to Machine** as the application type. 4. Select **Save**. -5. Go to the **Details** page and copy the app keys: - - - Domain - - Client ID - - Client Secret - You will need these details when you call the Kinde Management API. - -### 2. Authorize and add scopes +### 2. Authorize the Management API 1. On your application settings page, select **APIs**. 2. Select the three dots next to the **Kinde Management API**, then choose **Authorize application**. -3. Select the three dots again, now select **Manage scopes**. -4. Enable the scopes you want to include for this application. (e.g., `read:users`, `write:users`, `read:roles`, `write:roles`) + +### 3. Add scopes + +1. On the **APIs** page, select the three dots in the **Kinde Management API** row, now select **Manage scopes**. +2. Enable the scopes you want to include for this application. (e.g., `read:users`, `write:users`, `read:roles`, `write:roles`) -### 4. Test endpoints in the Management API page +### 2. Test endpoints -1. Select **Use test token** button from the token page. The **Kinde Management API** page will open with the test token pre-populated. Here you can test the relevant endpoints. +1. The **Kinde Management API** page will open with the test token pre-populated. Here you can test the relevant endpoints. ![kinde management api page](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/72840d32-1f90-4fc3-30e9-40074f163f00/public) @@ -99,5 +107,10 @@ This guide shows you how to set up a new machine to machine (M2M) application, a 4. Select **Send** and you will see the response JSON. -- Other methods: Follow [this guide](/developer-tools/kinde-api/access-token-for-api/) that includes several different options for getting an access token, including via Postman. +## Next steps + +Now that you have finished setting up an authorized M2M app, take a look at the following guides: +- [Call the Management API](/developer-tools/kinde-api/access-token-for-api/) for production use +- [Call the API using Postman](/developer-tools/kinde-api/call-the-api-postman/) +- [Learn about scopes](/developer-tools/kinde-api/about-m2m-scopes/) \ No newline at end of file From afa02586e90db928c89d99e5af00f6b97f02555c Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Thu, 30 Apr 2026 21:03:21 +0600 Subject: [PATCH 04/14] Remove the redundant node page --- .../kinde-api/access-token-for-api.mdx | 2 +- .../kinde-api/api-example-node.mdx | 134 ------------------ .../kinde-api/connect-to-kinde-api.mdx | 36 ++++- 3 files changed, 33 insertions(+), 139 deletions(-) delete mode 100644 src/content/docs/developer-tools/kinde-api/api-example-node.mdx diff --git a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx index 63ad84fca..f971a4bfd 100644 --- a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx @@ -575,7 +575,7 @@ dataTask.resume() 2. You will get the appropriate response from the Management API. -## Use the Kinde Management API JS SDK +## JavaScript SDK As an alternative to making HTTP calls, you can also use the [Kinde Management API JS](https://github.com/kinde-oss/management-api-js/) SDK. diff --git a/src/content/docs/developer-tools/kinde-api/api-example-node.mdx b/src/content/docs/developer-tools/kinde-api/api-example-node.mdx deleted file mode 100644 index 2f6ab890f..000000000 --- a/src/content/docs/developer-tools/kinde-api/api-example-node.mdx +++ /dev/null @@ -1,134 +0,0 @@ ---- -page_id: f99396dc-d158-4d37-a98b-386485b1ff69 -title: Call the Kinde Management API using Node.js -sidebar: - order: 4 - label: "Call the API - Node.js" -tableOfContents: - maxHeadingLevel: 3 -relatedArticles: - - 6bf993fc-a195-4836-8eaf-133812be8876 - - 51899f7f-3436-46e0-9a1b-6ecc3603a0df - - cffc17b9-2d10-4f42-8c84-a12b263a6040 -topics: - - developer-tools - - kinde-api -sdk: [] -languages: - - javascript - - nodejs -audience: - - developers -complexity: intermediate -keywords: - - nodejs - - management api - - access token - - m2m application - - api example - - fetch -updated: 2024-01-15 -featured: false -deprecated: false -ai_summary: NodeJS example demonstrating how to obtain access tokens and call the Kinde Management API using fetch and OAuth2 client credentials ---- - -Learn how to call the Kinde Management API using Node.js. - -### What you need - -- A Kinde M2M application with Management API access, appropriate scopes, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) -- [Node.js](https://nodejs.org/) version 20+ installed on your machine - -## Call the API - -### 1. Get an access token - -1. Get the app keys for your M2M application (Domain, Client ID, and Client Secret). -2. Make a POST request to the `https://.kinde.com/oauth2/token` endpoint using the following code sample: - - Make sure to replace ``, `` and `` with your own details. - - ```javascript - const getAccessToken = async () => { - try { - const searchParams = { - grant_type: "client_credentials", - client_id: "", - client_secret: "", - audience: "https://.kinde.com/api" - }; - - const res = await fetch("https://.kinde.com/oauth2/token", { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded" - }, - body: new URLSearchParams(searchParams) - }); - const token = await res.json(); - console.log({token}); - } catch (err) { - console.error(err); - } - }; - - await getAccessToken(); - ``` -3. You will get a response with an access token. The response will contain a signed JWT containing claims including the scopes the token is allowed to access and the expiry time. - - ```json - { - "access_token": "...", - "token_type": "Bearer", - "expires_in": 3600 - } - ``` - -Here is an example of a decoded access token: - - ```json - { - "aud": [ - "https://example.kinde.com/api - ], - "azp": "bd69bb9fe5db44a38b6b2dacd1f4b451", - "exp": 1729812040, - "gty": [ - "client_credentials - ], - "iat": 1729725640, - "iss": "https://example.kinde.com", - "jti": "6f091ebe-44ba-4afc-bd2f-05fcccafc89e", - "scope": "read:users update:users" - } - ``` - -### 2. Use the access token - -1. Use the access token to call the Kinde management API: - - ```javascript - const getUsers = async () => { - const accessToken = await getAccessToken(); - - const headers = { - Accept: "application/json", - Authorization: `Bearer ${accessToken}` - }; - try { - const res = await fetch("https://.kinde.com/api/v1/users", { - method: "GET", - headers: headers - }); - const data = await res.json(); - console.log({data}); - } catch (err) { - console.error(err); - } - }; - ``` - -2. You will get the appropriate response from the Management API. - -3. Repeat the steps for any other [Kinde API endpoints](/kinde-apis/management/) you want to test. \ No newline at end of file diff --git a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx index b83d2f6d7..2bafa5afd 100644 --- a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx @@ -83,10 +83,11 @@ This guide shows you how to set up and authorize a new M2M application with the ### 1. Get the test token -1. Go to your M2M application > **APIs** page and select the **Kinde Management API** row. -2. Select **Test** in the menu. -3. Select the M2M application from the dropdown, and select **Get token**. -4. Select the **Use test token** button to open the management API page with the test token pre-populated. +1. Go to your Kinde dashboard > **Settings > Environment > APIs** +2. Select **View details** on the **Kinde Management API**. +3. Select **Test** in the menu. +4. Select your M2M application from the dropdown, and select **Get token**. +5. Select the **Use test token** button to open the management API page with the test token pre-populated. ![kinde test token](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/321a49c0-f629-4c7a-9ef2-349ad0f31f00/public) @@ -107,10 +108,37 @@ This guide shows you how to set up and authorize a new M2M application with the 4. Select **Send** and you will see the response JSON. + Sample response: + + ```json + { + "code": "OK", + "roles": [ + { + "id": "1234", + "key": "admin", + "name": "Admin", + "description": null, + "is_default_role": false + }, + { + "id": "5678", + "key": "content-moderator", + "name": "Content Moderator", + "description": "Can read and update posts for content moderation purposes", + "is_default_role": false + } + ], + "message": "Success", + "next_token": "Mjo6Om5hbWVfYXNj" + } + ``` + ## Next steps Now that you have finished setting up an authorized M2M app, take a look at the following guides: - [Call the Management API](/developer-tools/kinde-api/access-token-for-api/) for production use - [Call the API using Postman](/developer-tools/kinde-api/call-the-api-postman/) +- [Automate and replicate your Kinde configurations](/developer-tools/guides/manage-kinde-configuration/) - [Learn about scopes](/developer-tools/kinde-api/about-m2m-scopes/) \ No newline at end of file From 20ce8c490807054eb21dd376daf5c0cfad939a02 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Sat, 2 May 2026 20:44:52 +0600 Subject: [PATCH 05/14] reorder management api in sidebar --- src/data/sidebarData.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/data/sidebarData.ts b/src/data/sidebarData.ts index 57f0230a8..af7f9d1c7 100644 --- a/src/data/sidebarData.ts +++ b/src/data/sidebarData.ts @@ -66,11 +66,6 @@ const sidebarData = [ cardLink: "/developer-tools/about/our-sdks/", items: [ {label: "Overview", autogenerate: {directory: "developer-tools/about"}, collapsed: false}, - { - label: "Special guides", - autogenerate: {directory: "developer-tools/guides"}, - collapsed: false - }, { label: "Front end SDKs", autogenerate: {directory: "developer-tools/sdks/frontend"}, @@ -95,6 +90,11 @@ const sidebarData = [ label: "Account API", autogenerate: {directory: "developer-tools/account-api"}, collapsed: false + }, + { + label: "Special guides", + autogenerate: {directory: "developer-tools/guides"}, + collapsed: false } ] }, From b8b12131b239b624e83473db5159ee9479da2a40 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Sat, 2 May 2026 21:14:57 +0600 Subject: [PATCH 06/14] update the scopes page --- .../kinde-api/about-m2m-scopes.mdx | 163 +++++++++++++++--- 1 file changed, 136 insertions(+), 27 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx b/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx index d81ca14ac..e5a3b5673 100644 --- a/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx +++ b/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx @@ -1,22 +1,26 @@ --- page_id: 6bf993fc-a195-4836-8eaf-133812be8876 title: About scopes in Kinde Management API -description: "Comprehensive guide to M2M scopes for Kinde Management API, including scope examples and management procedures" +description: "M2M scopes control which Kinde Management API endpoints an application can access. Learn how to configure and request scopes." sidebar: order: 8 label: "About scopes" +tableOfContents: + maxHeadingLevel: 3 relatedArticles: - 51899f7f-3436-46e0-9a1b-6ecc3603a0df - 50284476-2442-414c-af20-01ed3ef4ca4e - 601dd8c5-6ee1-474f-ad36-201e65280462 app_context: - - m: settings - s: applications - - m: user + - m: api_details + s: scopes + - m: application_details s: apis topics: - developer-tools - kinde-api + - authentication + - authorization sdk: [] languages: - shell @@ -25,37 +29,43 @@ audience: - admins complexity: intermediate keywords: - - scopes - - jwt - - api access - - permissions + - m2m scopes + - machine to machine + - jwt scopes + - scope claim + - api access control - read:users - - write:users + - update:users - read:roles - - write:roles -updated: 2024-01-15 + - update:roles + - create:organizations + - feature flags + - environment variables + - webhooks + - connections + - permissions + - client credentials +updated: 2026-05-02 featured: false deprecated: false -ai_summary: Comprehensive guide to M2M scopes for Kinde API access, including scope examples and management procedures +ai_summary: "Scopes in the Kinde Management API are JWT claims that control which endpoints a machine-to-machine (M2M) application can access. Each scope follows a verb:resource pattern — for example, read:users or update:roles — and is assigned when you authorize an M2M application in your Kinde dashboard. By default, a token request returns all scopes enabled for that application, but you can request a subset by passing a scope parameter in the token request body. This is useful for limiting what a specific token can do, reducing your attack surface. The page covers how to add, update, and manage scopes via Settings > Applications, and includes a reference table of the most commonly used scopes grouped by resource type: users, organizations, organization users, roles, permissions, applications, feature flags, environments, connections, and webhooks. The general guidance is to enable only the minimum scopes an application requires." --- -The Kinde management API uses JSON Web Tokens (JWTs) to authenticate requests. The token’s scopes claim indicates which endpoints can be accessed when calling the API. +The Kinde management API uses JSON Web Tokens (JWTs) to authenticate requests. The `scope` claim in a token controls which API endpoints the application can access. ## Example scopes -- `read:users` for fetching user details. -- `write:users` for modifying user details. -- `read:roles` or `write:roles` for managing roles. +- `read:users` — read user details +- `update:users` — update user details +- `read:roles` or `update:roles` — manage roles -You can select scopes when you authorize a new application or you can add scopes to an existing application. We recommend adding as few scopes as you need, to maintain API security. +Scopes are assigned when you authorize an M2M application and can be updated at any time. Enable only what you need — fewer scopes means a smaller attack surface. -## Request scopes in the body of an access token request +## Request a subset of scopes -By default token requests for an authorized application will return all the scopes enabled below. You can also optionally ask for a subset of enabled scopes to be returned by including them in the body of the access token request. You might do this to add more security to access requests, or because you want your users to be very specific about scopes in their requests. +By default, a token request returns all scopes enabled for that application. To limit the scopes in a token, include a `scope` parameter in the request body. This is useful when you want tighter control over what a specific token can access. -Example request - -``` +```bash curl --request POST \ --url 'https://.kinde.com/oauth2/token' \ --header 'content-type: application/x-www-form-urlencoded' \ @@ -66,12 +76,111 @@ curl --request POST \ --data 'scope=read:users update:users' ``` -## Add or modify scopes for accessing the Kinde Management API +## Add or update scopes on an M2M application -Follow this procedure if you already have an application and you experience a scope error, if you want to add scopes for an application, or remove scopes to tighten security. +Use this if you're seeing a scope error, need to grant additional access, or want to restrict what an application can do. -1. Go to **Settings > Applications** and select the relevant M2M application. +1. Go to **Settings > Applications** and select the relevant M2M application. 2. On the left, select **APIs**. -3. Select the three dots next to the Kinde management API, then choose **Manage scopes**. -4. Select the scopes you want to include in the token. For maximum security only enable the minimum scopes you require. +3. Select the three dots next to the Kinde management API, then choose **Manage scopes**. +4. Select the scopes to include in the token. Enable only the minimum scopes required. 5. Select **Save**. + +## Available scopes + +These are the most commonly used scopes. Your Kinde dashboard shows the full list when you configure an M2M application. + +### Users + +| Scope | Description | +|---|---| +| `read:users` | Read user details | +| `create:users` | Create users | +| `update:users` | Update user details | +| `delete:users` | Delete users | + +### Organizations + +| Scope | Description | +|---|---| +| `read:organizations` | Read organizations | +| `create:organizations` | Create organizations | +| `update:organizations` | Update organizations | +| `delete:organizations` | Delete organizations | + +### Organization users + +| Scope | Description | +|---|---| +| `read:organization_users` | Read users in an organization | +| `create:organization_users` | Add users to an organization | +| `update:organization_users` | Update organization user details | +| `delete:organization_users` | Remove users from an organization | + +### Roles + +| Scope | Description | +|---|---| +| `read:roles` | Read roles | +| `create:roles` | Create roles | +| `update:roles` | Update roles | +| `delete:roles` | Delete roles | +| `read:organization_user_roles` | Read roles assigned to organization users | +| `create:organization_user_roles` | Assign roles to organization users | +| `delete:organization_user_roles` | Remove roles from organization users | + +### Permissions + +| Scope | Description | +|---|---| +| `read:permissions` | Read permissions | +| `create:permissions` | Create permissions | +| `update:permissions` | Update permissions | +| `delete:permissions` | Delete permissions | + +### Applications + +| Scope | Description | +|---|---| +| `read:applications` | Read application details | +| `create:applications` | Create applications | +| `update:applications` | Update application details | +| `delete:applications` | Delete applications | + +### Feature flags + +| Scope | Description | +|---|---| +| `read:feature_flags` | Read feature flags | +| `create:feature_flags` | Create feature flags | +| `update:feature_flags` | Update feature flags | +| `delete:feature_flags` | Delete feature flags | + +### Environments + +| Scope | Description | +|---|---| +| `read:environments` | Read environment details | +| `update:environments` | Update environment settings | +| `read:environment_variables` | Read environment variables | +| `create:environment_variables` | Create environment variables | +| `update:environment_variables` | Update environment variables | +| `delete:environment_variables` | Delete environment variables | + +### Connections + +| Scope | Description | +|---|---| +| `read:connections` | Read connection details | +| `create:connections` | Create connections | +| `update:connections` | Update connections | +| `delete:connections` | Delete connections | + +### Webhooks + +| Scope | Description | +|---|---| +| `read:webhooks` | Read webhooks | +| `create:webhooks` | Create webhooks | +| `update:webhooks` | Update webhooks | +| `delete:webhooks` | Delete webhooks | From fca7351549e10b83ebe1daf856d18513ec8e6ad4 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Sun, 3 May 2026 14:35:16 +0600 Subject: [PATCH 07/14] update the postman tutorial with updated screenshots, steps, and common errors and troubleshooting --- .../kinde-api/call-the-api-postman.mdx | 273 ++++++++++-------- 1 file changed, 157 insertions(+), 116 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx b/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx index 24e12c57a..1be328b97 100644 --- a/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx +++ b/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx @@ -1,6 +1,7 @@ --- page_id: cdb62fdc-cc83-4247-a0e0-7196bc7edb3e title: Call the Kinde Management API with Postman +description: This guide walks you through setting up Postman to authenticate with the Kinde Management API using OAuth 2.0 client credentials, and shows you how to make your first API calls to list and create users. sidebar: order: 3 label: "Call the API - Postman" @@ -17,14 +18,10 @@ app_context: topics: - developer-tools - kinde-api + - authentication + - api-testing sdk: [] languages: - - csharp - - go - - java - - javascript - - objective-c - - php - shell audience: - developers @@ -35,140 +32,184 @@ keywords: - m2m application - client credentials - oauth2 + - oauth 2.0 - api authentication -updated: 2024-01-15 + - postman + - postman environment + - bearer token + - audience parameter + - kinde management api + - client credentials flow + - api testing + - create users api + - list users api + - postman tutorial + - postman troubleshooting +updated: 2026-05-03 featured: false deprecated: false -ai_summary: Comprehensive guide to obtaining access tokens and calling the Kinde Management API using M2M applications and OAuth2 client credentials flow +ai_summary: "This guide explains how to call the Kinde Management API using Postman with OAuth 2.0 client credentials. It covers three main areas: setting up a Postman environment, obtaining an access token, and testing API endpoints. In the environment setup, you configure variables for your Kinde domain, M2M client ID, and client secret, and mark the secret as sensitive. To get an access token, you create a Postman collection, configure OAuth 2.0 with the client credentials grant type, set the access token URL, and add the audience parameter in the advanced token request settings. The guide then demonstrates two API calls — fetching a list of users via GET /api/v1/users and creating a new user via POST /api/v1/user with email, phone, and username identities. A troubleshooting section addresses three common errors: client authentication failure (invalid credentials), a 403 missing audience error (incorrect or missing audience value), and a 403 SCOPE_MISSING error (missing scopes on the M2M application). Prerequisites include a Postman client, a Kinde M2M application with Management API access, and the create:users and read:users scopes." --- -Learn how to call the Kinde Management API using Postman. +This guide walks you through setting up Postman to authenticate with the Kinde Management API using OAuth 2.0 client credentials, and shows you how to make your first API calls to list and create users. ### What you need -- A Kinde M2M application with Management API access, appropriate scopes, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) - A [Postman client](https://www.postman.com/) installed on your machine +- A Kinde M2M application with Management API access, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) +- Minimum scopes for this example: `create:users` and `read:users` -## Postman guide +## Postman tutorial -### 1. Set up Postman environment +### 1. Create a Postman environment -We recommend that you set up a Postman environment and test this in a non-production environment first. Here's some [troubleshooting solutions](/developer-tools/kinde-api/troubleshoot-kinde-api/) in case you need them. +We recommend that you set up a Postman environment and test this in a non-production space first. -1. Add your Kinde machine to machine application keys as environment variables. +1. On your Postman client, select the **No environment** dropdown from the top right and select the plus icon to create a new environment. - Adding environment variables in Postman + ![Creating a new environment in Postman](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/060191ee-65c1-452f-1bc1-63ede028b200/socialsharingimage) -2. Select **Save** for the variables to persist. +2. Enter a name for the environment (e.g., Local). +3. Copy the [app keys from your M2M application](/developer-tools/kinde-api/connect-to-kinde-api/#4-get-app-keys) and enter them as environment variables: + + - `KINDE_DOMAIN` - `https://.kinde.com` + - `M2M_CLIENT_ID` - the client ID from your M2M application + - `M2M_CLIENT_SECRET` - the client secret from your M2M application + + ![Local environment variables in Postman](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/8b4bb03e-ef5d-482a-7cd0-406a3d07a300/socialsharingimage) + +4. Mark the client secret variable as **Sensitive** so it will not accidentally leak to your team. ### 2. Get the access token -1. Go to **Collections**. Create a new collection called **Kinde**. -2. In the three dots menu next to the new **Kinde** folder, select **Add request**. - - Adding a request in Postman - -3. Go to the **Authorization** section and set the **Type** to **OAuth 2.0** and set the **Header Prefix** to **Bearer**. -4. In the **Configure New Token > Configuration options** section, set the **Grant Type** to **Client Credentials**. -5. Enter the **Access Token URL** using the domain variable you created above. For example, `{{business_domain}}/oauth2/token`. Note that even if you use a custom domain, the access token URL should still use your `https://.kinde.com` domain. - - Entering the access token URL - -6. Enter the **Client ID** and **Client Secret** using the environment variables you created earlier or by copying them from the Kinde application. -7. Set the **audience** to `{{business_domain}}/api`. To do this: - - Scroll down click **Advanced**. In the **Token request** section, select the `audience` key and enter the above URL in the **Value** field. Ensure it is being sent in the `body` of the request - - - -8. Go to the **Headers** tab. - - Setting the Content-Type value in Postman - -9. Select **Accept** and ensure the value is `application/json`. -10. In the **Authorization** section, select **Get New Access Token**. You should see a confirmation message. -11. Select **Proceed**. - - Access Token in Postman - -12. Select **Use Token**. You should now have the access token for making requests to the Kinde management API. See the [Kinde API documentation](/kinde-apis/management/) for all the available end points. +1. Go to **Collections**. Create a new collection (e.g., **Kinde**). + + ![Creating a new collection in Postman](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/10a9036f-bd38-4359-e352-698abb51b000/socialsharingimage) + +2. In the three dots menu next to the new **Kinde** folder, select **Add request**. +3. Go to the **Authorization** section and set the **Type** to **OAuth 2.0** and make sure the **Header Prefix** is set to **Bearer**. + + ![authorization configuration in Postman](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/e3e6269f-abb4-45b0-246f-a8c4f6de4500/socialsharingimage) + +4. In the **Configure New Token** section, set the **Grant Type** to **Client Credentials**. + + ![grant type configuration in Postman](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/f5f02827-18b1-45cf-3c94-5cea38a66600/socialsharingimage) + +5. Enter the **Access Token URL** using the domain variable you created above: `{{KINDE_DOMAIN}}/oauth2/token`. + + + +6. Enter the **Client ID** and **Client Secret** using the environment variables you created earlier. +7. Scroll down and select **Advanced**. In the **Token request** section, add a new `audience` key and enter `{{KINDE_DOMAIN}}/api` in the **Value** field. Ensure it is being sent in the `Request Body`. + + ![advanced audience parameter in Postman token request](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/960e0dd8-99aa-4745-c30b-ced939479400/socialsharingimage) + +8. Scroll down to the **Authorization** section and select **Get New Access Token**. You should see a confirmation message. +9. Select **Proceed**. +10. Select **Use Token**. You now have an access token for making requests to the Kinde Management API. Optionally, set a name for the token for easier identification. + + ![M2M access token obtained in Postman](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/552f3abd-c13a-4f5a-b4b7-f6cda406e200/socialsharingimage) ### 3. Test the API endpoints -You can test your API access in Postman by sending a `GET` request to any Kinde API endpoint. See the [Kinde Management API library](/kinde-apis/management/) for options. +**Get users list from API:** + +1. Create a new request. +2. In the URL field, use the `/api/v1/users` endpoint: `{{KINDE_DOMAIN}}/api/v1/users` +3. Go to the **Authorization** section and select **OAuth 2.0** as the Auth Type. +4. Select the **Token** from the previously saved token. +5. Select **Send**. +6. You should see a list of your account users in the response body. + + ![users response body in Postman](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/c4be21e1-a1a4-498b-723e-f71b06076c00/socialsharingimage) + +**Create a new user with API:** + +1. Create a new request, set the type to **POST** and the URL to `/api/v1/user`. +2. Go to **Body**, select **raw** and enter the following JSON: + + ```json + { + "profile": {}, + "identities": [ + {"type": "email", "is_verified": true, "details": {"email": "jamesbond@mi6.com"}}, + { + "type": "phone", + "is_verified": false, + "details": {"phone": "+61426148233", "phone_country_id": "au"} + }, + {"type": "username", "details": {"username": "jamesbond007"}} + ] + } + ``` + This will create a new user in your Kinde business. + +3. Set the **Authorization** as before. +4. Select **Send**. +5. You should see a success response with the new user in the response body section. + + ```json + { + "id": "kp_1234", + "created": true, + "identities": [ + { + "type": "email", + "result": { + "created": true + } + }, + { + "type": "phone", + "result": { + "created": true + } + }, + { + "type": "username", + "result": { + "created": true + } + } + ] + } + ``` +6. Go to your Kinde dashboard > **Users** and you should see the new user in the list. + +## Troubleshooting + +### Authentication failed + +**Error message:** + +invalid_client, Description: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). + +**Solution:** + +Verify that you have copied the correct domain, client ID, and client secret, with no typos. + +### Missing audience + +**Error message:** + +403 Forbidden: Missing or incorrect Management API audience. + +**Solution:** + +Verify that you have added the correct audience value `https://.kinde.com/api` to the `audience` parameter in Step 2 of this doc. + +### Scope is missing -Here’s an example using the `Get users` endpoint. +**Error message:** -1. Create a new `GET` request. -2. Enter a URL that contains the `/users` endpoint, e.g. `https://.kinde.com/api/v1/users` . +403 Forbidden: SCOPE_MISSING - Entering a Request URL in Postman +**Solution:** -3. Send the request. It should return your users in the body section. If it does, the connection is successful. +Add the missing scopes to your M2M application, get a new access token and try again. - Response body in Postman +## Next steps -4. Repeat from step 1 for any other [Kinde API endpoints](/kinde-apis/management/) you want to test. \ No newline at end of file +Now that Postman is configured to call the Kinde Management API, explore it to automate your account actions. Check out the [Kinde Management API](/kinde-apis/management/) for all available endpoints. From c932401fb682b4e6060ab8f049d53d94240a5f50 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Sun, 3 May 2026 16:22:14 +0600 Subject: [PATCH 08/14] update the main management api calling doc --- .../kinde-api/access-token-for-api.mdx | 109 +++++++++++++----- 1 file changed, 82 insertions(+), 27 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx index f971a4bfd..ad07a8323 100644 --- a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx @@ -1,6 +1,7 @@ --- page_id: fa5b704d-1682-47df-ac41-524b56096e79 title: Call the Kinde Management API +description: Use the OAuth2 client credentials flow to get a machine-to-machine (M2M) access token and make authenticated requests to the Kinde Management API. sidebar: order: 2 label: "Call the API - General Guide" @@ -17,6 +18,9 @@ app_context: topics: - developer-tools - kinde-api + - authentication + - api-access + - m2m sdk: [] languages: - csharp @@ -25,7 +29,10 @@ languages: - javascript - objective-c - php + - python + - ruby - shell + - swift audience: - developers complexity: intermediate @@ -33,27 +40,36 @@ keywords: - management api - access token - m2m application + - machine to machine - client credentials - oauth2 + - oauth2 token - api authentication -updated: 2024-01-15 + - bearer token + - jwt access token + - kinde api + - api authorization + - scope parameter + - token scopes + - kinde subdomain +updated: 2026-05-03 featured: false deprecated: false -ai_summary: "Comprehensive guide to obtaining access tokens and calling the Kinde Management API using M2M applications and OAuth2 client credentials flow" +ai_summary: "This guide explains how to authenticate with the Kinde Management API using the OAuth2 client credentials flow. It covers the full process: starting with a Kinde M2M (machine-to-machine) application that has Management API access and the required scopes configured, then making a POST request to the /oauth2/token endpoint to exchange your client ID and client secret for a signed JWT access token. The guide provides code examples in cURL, C#, Go, Java, Node.js, Objective-C, PHP, Python, Ruby, and Swift. It also explains how to decode the returned JWT and understand its claims, including audience, issued-at time, and granted scopes. Once you have the token, the guide shows how to pass it as a Bearer token in the Authorization header to make authenticated API calls — using the list users endpoint as a worked example. Finally, it covers the optional scope parameter, which lets you request a restricted subset of your M2M application's enabled scopes, reducing the token's permission surface for improved security." --- -Learn how to call the Kinde Management API using client credentials. +Use the OAuth2 client credentials flow to get a machine-to-machine (M2M) access token and make authenticated requests to the Kinde Management API. ### What you need -- A Kinde M2M application with Management API access, appropriate scopes, and app keys [see the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) +- A Kinde M2M application with Management API access, appropriate scopes, and app keys — see the [quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) ## Call the API ### 1. Get an access token 1. Get the app keys for your M2M application (Domain, Client ID, and Client Secret). -2. Make a POST request to the `https://.kinde.com/oauth2/token` endpoint using your prefered programming language below: +2. Make a POST request to the `https://.kinde.com/oauth2/token` endpoint using your preferred programming language: Make sure to replace ``, `` and `` with your own details. @@ -312,28 +328,43 @@ dataTask.resume() -3. You will get a response with an access token. The response will contain a signed JWT containing claims including the scopes the token is allowed to access and the expiry time. Here is an example of a decoded access token: +3. The response includes an access token: -```json -{ - "aud": [ - "https://example.kinde.com/api - ], - "azp": "bd69bb9fe5db44a38b6b2dacd1f4b451", - "exp": 1729812040, - "gty": [ - "client_credentials - ], - "iat": 1729725640, - "iss": "https://example.kinde.com", - "jti": "6f091ebe-44ba-4afc-bd2f-05fcccafc89e", - "scope": "read:users update:users" -} -``` + ```jsonc + { + "access_token": "", // the JWT access token + "expires_in": 86399, + "scope": "", // any sub scopes you defined in the request + "token_type": "Bearer", + } + ``` + + The `access_token` field will contain a signed JWT for you to use in the API requests. Use the [Kinde Online JWT decoder](https://www.kinde.com/tools/online-jwt-decoder/) to decode the token. + + Here is the decoded M2M access token: + + ```json + { + "aud": [ + "https://.kinde.com/api" + ], + "azp": "", + "exp": 1777887031, + "gty": [ + "client_credentials" + ], + "iat": 1777800631, + "iss": "https://.kinde.com", + "jti": "61859f4b-75e1-4ac8-bda7-8a69a5f6660e", + "scope": "create:users read:users", + "scp": [], + "v": "2" + } + ``` ### 2. Use the access token -1. Include the access token in the Authorization header of your request. For example to get all users you would call: +1. Include the access token in the `Authorization` header of your request. For example, to retrieve all users: @@ -573,10 +604,34 @@ dataTask.resume() -2. You will get the appropriate response from the Management API. +2. The Management API returns the appropriate response. + +## The scope parameter + +You can include an optional `scope` parameter in the request to the `/oauth2/token` endpoint to request a subset of scopes for the token. + +For example, if you have enabled the following scopes for your M2M application: + +- `create:users` +- `read:users` +- `update:users` +- `delete:users` + +Using the `scope` parameter, you can request a subset of those scopes for the token — in this case, `create:users` and `read:users`. + +```bash +curl --request POST \ + --url 'https://.kinde.com/oauth2/token' \ + --header 'content-type: application/x-www-form-urlencoded' \ + --data grant_type=client_credentials \ + --data 'client_id=' \ + --data 'client_secret=' \ + --data 'audience=https://.kinde.com/api' \ + --data 'scope=create:users read:users' +``` -## JavaScript SDK +The token will be scoped to only the permissions you requested, which reduces the attack surface and limits exposure if the token is compromised. -As an alternative to making HTTP calls, you can also use the [Kinde Management API JS](https://github.com/kinde-oss/management-api-js/) SDK. +## Next steps -You can use it to automatically obtain tokens for, and interact with the Kinde management API. +With a working access token, you can now call the Management API to automate account actions. See the [Kinde Management API](/kinde-apis/management/) for all available endpoints. \ No newline at end of file From 13a19dbb150c909c582a47e6fbabc61d3fb83f8e Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Sun, 3 May 2026 17:07:39 +0600 Subject: [PATCH 09/14] add new doc, management api js sdk --- .../kinde-api/management-api-js.mdx | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 src/content/docs/developer-tools/kinde-api/management-api-js.mdx diff --git a/src/content/docs/developer-tools/kinde-api/management-api-js.mdx b/src/content/docs/developer-tools/kinde-api/management-api-js.mdx new file mode 100644 index 000000000..d374901d2 --- /dev/null +++ b/src/content/docs/developer-tools/kinde-api/management-api-js.mdx @@ -0,0 +1,186 @@ +--- +page_id: 758b6a4d-e28f-4676-8942-78769b33f6be +title: Call the Kinde Management API from JavaScript Backends +description: "Install and configure @kinde/management-api-js on the server to call the Kinde Management API with M2M credentials." +sidebar: + order: 4 + label: "Call the API - JavaScript Backends" +tableOfContents: + maxHeadingLevel: 3 +relatedArticles: + - 50284476-2442-414c-af20-01ed3ef4ca4e + - fa5b704d-1682-47df-ac41-524b56096e79 + - 6bf993fc-a195-4836-8eaf-133812be8876 +app_context: + - m: settings + s: applications +topics: + - developer-tools + - kinde-api + - backend + - javascript + - sdk + - m2m + - user-management +sdk: + - management-api-js +languages: + - javascript + - typescript +audience: + - developers +complexity: intermediate +keywords: + - management api + - javascript sdk + - typescript sdk + - m2m + - machine to machine + - backend + - server + - server-side + - "@kinde/management-api-js" + - init + - getUsers + - createUser + - getUserData + - environment variables + - KINDE_DOMAIN + - KINDE_MANAGEMENT_CLIENT_ID + - KINDE_MANAGEMENT_CLIENT_SECRET + - client credentials + - node.js + - user management +updated: 2026-05-03 +featured: false +deprecated: false +ai_summary: "This guide explains how to use the @kinde/management-api-js JavaScript SDK to call the Kinde Management API from a server-side application. The SDK abstracts the OAuth2 client credentials flow, so you don't need to manually request tokens or construct raw HTTP requests. It is strictly for backend use — the M2M client secret must never be exposed in browser or client-side code. The guide covers three setup steps: installing the package via npm, yarn, or pnpm; setting the three required environment variables (KINDE_DOMAIN, KINDE_MANAGEMENT_CLIENT_ID, KINDE_MANAGEMENT_CLIENT_SECRET); and calling init() once to configure the SDK before making any API calls. Alternatively, credentials can be passed directly to init() as an object. Two worked examples are included: fetching all users with Users.getUsers(), fetching a single user by ID with Users.getUserData(), and creating a new user with Users.createUser() using a profile and identities array. The expected JSON response for user creation is shown, including the generated user ID and a created flag per identity. The guide links to the full Kinde Management API reference for all available resources and parameters." +--- + +The `@kinde/management-api-js` package is a JavaScript SDK that wraps the Kinde Management API. Instead of manually handling token exchange and raw HTTP requests, you import typed functions for each resource and call them directly. + + + +### What you need + +- A Kinde M2M application with Management API access and the required scopes — see the [quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) +- A JavaScript backend project such as the [Kinde Next.js SDK](/developer-tools/sdks/backend/nextjs-sdk/) +- Node.js 20 or higher + +## Setup guide + +### 1. Install the package + + + +### 2. Set environment variables + +1. Add the following to your project's `.env` file. You can find these values on the **Details** page in your Kinde M2M application. [Read the quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/#quickstart-guide). + + ```bash + KINDE_DOMAIN=https://.kinde.com + KINDE_MANAGEMENT_CLIENT_ID= + KINDE_MANAGEMENT_CLIENT_SECRET= + ``` + +2. You can also pass configuration directly to `init()` if you prefer not to use environment variables: + + ```typescript + import { init } from "@kinde/management-api-js"; + + init({ + kindeDomain: "https://.kinde.com", + clientId: "", + clientSecret: "", + }); + ``` + +### 3. Initialize and call the API + +1. Import and call `init()` once before making any API calls — this sets up the SDK with your environment variables. + + ```typescript + import { init } from "@kinde/management-api-js"; + + init(); + ``` + +## Examples + +### Get users + +Fetch a list of all users in your Kinde business: + +```typescript +import { Users, init } from "@kinde/management-api-js"; + +init(); + +const { users } = await Users.getUsers(); +console.log(users); +``` + +To fetch a specific user by ID, pass an object with the user's `id`: + +```typescript +import { Users, init } from "@kinde/management-api-js"; + +init(); + +const userData = await Users.getUserData({ id: "kp_xxx" }); +console.log(userData); +``` + +### Create a user + +1. Use `Users.createUser()` to create a new user. Pass an `identities` array with one or more identity objects: + + ```typescript + import { Users, init } from "@kinde/management-api-js"; + + init(); + + const newUser = await Users.createUser({ + profile: { + given_name: "James", + family_name: "Bond", + }, + identities: [ + { + type: "email", + is_verified: true, + details: { email: "jamesbond@mi6.com" }, + }, + { + type: "username", + details: { username: "jamesbond007" }, + }, + ], + }); + + console.log(newUser.id); + ``` + +2. A successful response includes the new user's ID and a `created` flag for each identity: + + ```json + { + "id": "kp_1234", + "created": true, + "identities": [ + { "type": "email", "result": { "created": true } }, + { "type": "username", "result": { "created": true } } + ] + } + ``` + +3. Go to your Kinde dashboard > **Users** and you should see the new user in the list. + +## Next steps + +Now that you have the SDK set up, you can start calling the Management API to automate account actions. + +- [Kinde Management API reference](/kinde-apis/management/) +- [@kinde/management-api-js GitHub repository](https://github.com/kinde-oss/management-api-js) \ No newline at end of file From 16c611264c7ea9c456bde8da973baf3cea09d8c6 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Sun, 3 May 2026 17:49:10 +0600 Subject: [PATCH 10/14] update the search users doc with better structure and organization --- .../kinde-api/search-users-via-api.mdx | 136 ++++++++++++------ 1 file changed, 91 insertions(+), 45 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx b/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx index cd9f80820..e6425c87a 100644 --- a/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx @@ -1,10 +1,10 @@ --- page_id: 19b5cea3-bfce-4fe9-94ac-ddd8b872af3e -title: Tutorial - Search users via the Kinde Management API +title: Advanced User Search with the Kinde Management API description: "Guide to searching and filtering users via the Kinde Management API using query parameters and property filters" sidebar: order: 7 - label: "Tutorial - Search users" + label: "Guide - Advanced User Search" tableOfContents: maxHeadingLevel: 3 relatedArticles: @@ -14,6 +14,8 @@ relatedArticles: topics: - developer-tools - kinde-api + - user-management + - search-and-filtering sdk: [] languages: [] audience: @@ -22,54 +24,44 @@ audience: complexity: intermediate keywords: - search users + - filter users - api search - user filtering - properties filter - wildcard search - management api -updated: 2024-01-15 + - query parameter + - AND filter + - OR filter + - expand identities + - expand properties +updated: 2026-05-03 featured: false deprecated: false -ai_summary: Guide to searching and filtering users via the Kinde Management API using query parameters and property filters +ai_summary: "This guide explains how to search and filter users via the Kinde Management API using the GET /api/v1/search/users endpoint. It covers searching by name or email using the query parameter, and filtering by custom user properties using the properties[key]=value syntax. Developers can combine multiple property filters using AND logic (chained & parameters) or OR logic (comma-separated values), and use a wildcard (query=*) to match all users while applying property-level filters. The expand parameter can be added to include nested identities and properties in the response. An example JSON response is included." --- -You can search users and filter results via the Kinde Management API. You might need to do this to isolate users with specific properties defined, for example, to find users in a particular city. +Search and filter users via the Kinde Management API. Use this to find users with specific properties — for example, users in a particular city or industry. +### What you need -## Make an API search request +- A Kinde M2M application with Management API access — see the [connect to the Kinde API guide](/developer-tools/kinde-api/connect-to-kinde-api/) +- Scope: `read:users` +- A way to call the API (cURL, Postman, or the JS SDK) -Search with `GET` request: `/api/v1/search/users?query=searchterm` - -Add additional filters to the request: `&filterA=X&filterB=Y` - -Search and filter: GET `/api/v1/search/users?query=searchterm&filterA=X&filterB=Y` - -The query= part is for searching by user name or email, additional filters can be applied separately. For example, use /api/v1/search/users?query=*&properties[kp_user_city]=Sydney to find all users from Sydney based on the kp_user_city property. - -Here's some examples of search requests with different filter types. - -- Filter for users with multiple properties using AND(&) statements. - - - ```/api/v1/search/users?query=properties[kp_usr_last_name]=Swan&properties[kp_usr_industry]=Construction``` - - -- Filter for users with any property filter using OR(comma) statements. - - - ```/api/v1/search/users?query=properties[kp_usr_last_name]=Hornet,Swan``` - - -- Use a combination of filters. - - ```/api/v1/search/users?query=properties[kp_usr_last_name]=Hornet,Swan&properties[kp_usr_industry]=Construction&expand=identities,properties``` +## Search users by name or email +``` +GET /api/v1/search/users?query={searchterm} +``` -- Wildcards can also be used. +The `query` parameter searches against a user's name and email address. To match all users, use a wildcard (`*`). - ```/api/v1/search/users?query=*&properties[kp_usr_middle_name]=Hornet,Swan&properties[kp_usr_industry]=Construction&expand=identities,properties``` +``` +GET /api/v1/search/users?query=* +``` -### Example response +**Example response:** ```json { @@ -89,9 +81,7 @@ Here's some examples of search requests with different filter types. "failed_sign_ins": 0, "last_signed_in": "2025-02-12T18:02:23.614638+00:00", "created_on": "2025-02-12T18:02:23.614638+00:00", - "organizations": [ - "…" - ], + "organizations": ["…"], "identities": [ { "type": "…", @@ -113,15 +103,73 @@ Here's some examples of search requests with different filter types. } ``` +## Filter users by property + +Append `properties[key]=value` parameters to filter by [user properties](/manage-users/user-properties/about-user-properties/). You can combine `query` with property filters. + +``` +GET /api/v1/search/users?query={searchterm}&properties[{key}]={value} +``` + +For example, find all users from Sydney: + +``` +GET /api/v1/search/users?query=*&properties[kp_user_city]=Sydney +``` + +### Filter with AND (multiple conditions) + +Use multiple `properties[key]=value` parameters joined with `&` to require all conditions to match. + +``` +GET /api/v1/search/users?query=*&properties[kp_usr_last_name]=Swan&properties[kp_usr_industry]=Construction +``` + +Returns users whose last name is Swan **and** whose industry is Construction. + +### Filter with OR (comma-separated values) + +Use a comma-separated list of values within a single property filter to match any of them. + +``` +GET /api/v1/search/users?query=*&properties[kp_usr_last_name]=Hornet,Swan +``` + +Returns users whose last name is Hornet **or** Swan. + +### Combined filters + +Mix AND and OR conditions, and use `expand` to include nested data such as identities and properties in the response. + +``` +GET /api/v1/search/users?query=*&properties[kp_usr_last_name]=Hornet,Swan&properties[kp_usr_industry]=Construction&expand=identities,properties +``` + +Returns users whose last name is Hornet or Swan **and** whose industry is Construction, with their identities and properties expanded. + +### Use wildcards + +Use `query=*` to match all users, then narrow results with property filters. + +``` +GET /api/v1/search/users?query=*&properties[kp_usr_middle_name]=Hornet,Swan&properties[kp_usr_industry]=Construction&expand=identities,properties +``` + ## Search users by last activity date -Search users based on last activity date using the `active_since` parameter in the `GET /api/v1/users` endpoint. This searches for users by their last login date, useful for identifying inactive accounts or targeting recently active users. +``` +GET /api/v1/users?active_since={ISO8601datetime} +``` - ```/api/v1/users?active_since=2024-01-01T00:00:00Z``` +Use the `active_since` parameter to return users whose last login is on or after the specified date. This is useful for identifying inactive accounts or targeting recently active users. - The `active_since` parameter accepts an [ISO 8601 formatted date/time string](https://www.cdisc.org/kb/articles/when-would-i-use-iso8601-interval-format). Users with a last login date on or after the specified date will be returned. +``` +GET /api/v1/users?active_since=2024-01-01T00:00:00Z +``` -### Example response +The `active_since` value must be an [ISO 8601 formatted date/time string](https://www.cdisc.org/kb/articles/when-would-i-use-iso8601-interval-format). + +**Example response:** ```json { @@ -148,9 +196,7 @@ Search users based on last activity date using the `active_since` parameter in t "last_signed_in": "2026-01-28T14:26:02.448856+00:00" } ], - "organizations": [ - "…" - ], + "organizations": ["…"], "identities": [ { "type": "…", @@ -164,4 +210,4 @@ Search users based on last activity date using the `active_since` parameter in t ], "next_token": "…" } -``` \ No newline at end of file +``` From da73b3177a9a349c9523e7d79bfa3552f05c0794 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Sun, 3 May 2026 18:23:03 +0600 Subject: [PATCH 11/14] update the API rate limits page --- .../kinde-api/about-m2m-scopes.mdx | 4 +- .../kinde-api/access-token-for-api.mdx | 8 ++ .../kinde-api/api-rate-limits.mdx | 89 +++++++++++++------ 3 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx b/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx index e5a3b5673..4b591a7fa 100644 --- a/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx +++ b/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx @@ -1,10 +1,10 @@ --- page_id: 6bf993fc-a195-4836-8eaf-133812be8876 -title: About scopes in Kinde Management API +title: Kinde Management API Scopes description: "M2M scopes control which Kinde Management API endpoints an application can access. Learn how to configure and request scopes." sidebar: order: 8 - label: "About scopes" + label: "API Scopes" tableOfContents: maxHeadingLevel: 3 relatedArticles: diff --git a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx index ad07a8323..14f15cac6 100644 --- a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx @@ -632,6 +632,14 @@ curl --request POST \ The token will be scoped to only the permissions you requested, which reduces the attack surface and limits exposure if the token is compromised. +## How M2M tokens are calculated in Kinde + +An M2M token is generated each time you call the `/oauth2/token` Kinde API endpoint to retrieve an M2M access token. + +Where an access token is re-used - say where the same token is used to make another API request, this does not count as a new token. Similarly, where a token is re-used to make calls to other Kinde-registered APIs, this is also not counted as another token. + +Kinde’s free and Pro plans have a generous amount of M2M tokens included, before we start charging for them. For details, see our [pricing page](https://kinde.com/pricing/). + ## Next steps With a working access token, you can now call the Management API to automate account actions. See the [Kinde Management API](/kinde-apis/management/) for all available endpoints. \ No newline at end of file diff --git a/src/content/docs/developer-tools/kinde-api/api-rate-limits.mdx b/src/content/docs/developer-tools/kinde-api/api-rate-limits.mdx index e5f3af14d..47b0e5609 100644 --- a/src/content/docs/developer-tools/kinde-api/api-rate-limits.mdx +++ b/src/content/docs/developer-tools/kinde-api/api-rate-limits.mdx @@ -1,9 +1,12 @@ --- page_id: c944dcc9-35d1-4816-b2d3-a39fb0d3e68f -title: API rate limits -description: "Documentation on Kinde API rate limits, including rate and concurrency limiters, common causes, and graceful handling strategies" +title: Kinde Management API Rate Limits +description: "Understand Kinde API rate limits and concurrency limits, what causes 429 errors, and how to handle them gracefully." sidebar: order: 9 + label: "API Rate Limits" +tableOfContents: + maxHeadingLevel: 3 relatedArticles: - 6bf993fc-a195-4836-8eaf-133812be8876 - 51899f7f-3436-46e0-9a1b-6ecc3603a0df @@ -12,6 +15,8 @@ relatedArticles: topics: - developer-tools - kinde-api + - api-reference + - error-handling sdk: [] languages: [] audience: @@ -22,55 +27,81 @@ keywords: - api limits - 429 error - rate limiting + - too many requests - concurrency limiter + - rate limiter - exponential backoff - token bucket -updated: 2024-01-15 -featured: false -deprecated: false -ai_summary: Documentation on Kinde API rate limits, including rate and concurrency limiters, common causes, and graceful handling strategies + - RateLimit-Reset + - request throttling + - api stability + - bulk api limits + - page size limit + - retry strategy +updated: 2026-05-03 +ai_summary: "Kinde enforces two types of API limits: a rate limiter and a concurrency limiter. The rate limiter restricts payload size — capping GET responses at 500 results per page and bulk POST/PATCH requests at 100 objects — while the concurrency limiter caps the number of simultaneous in-flight requests. When either limit is exceeded, the API returns a 429 Too Many Requests status with a RateLimit-Reset header indicating how many seconds until the limit resets. Common triggers include high-frequency requests during migrations or analytics operations, resource-intensive list queries, requests with expansions, and sudden traffic spikes such as bulk user imports. The recommended handling strategy is exponential backoff with jitter: read the RateLimit-Reset header, wait progressively longer between retries, and add randomness to prevent multiple clients from retrying at the same time (thundering herd). An alternative is to implement a token bucket algorithm on the client side to proactively throttle outbound request volume before hitting the API. Integrations that require higher limits should contact Kinde support." --- -Kinde may rate limit incoming traffic to help maximise API stability and prevent bursts of requests from destabilizing API functions. +Kinde rate limits incoming traffic to maximise API stability and prevent bursts of requests from destabilizing API functions. -If you send a lot of requests in quick succession, you might see error responses with **code `429`**. +If you send too many requests in quick succession, you'll see error responses with **status `429`**. -For advice on handling these errors, see [Handle limiting gracefully](#handle-limiting-gracefully), below. If you suddenly see a rising number of rate-limited requests, contact Kinde support. +For advice on handling these errors, read the sections below. If you suddenly see a rising number of rate-limited requests, contact [Kinde support](https://www.kinde.com/support/). -## API limiters +## What limiters does the Kinde API use? -Kinde has several limiters in the API, including a rate limiter and a concurrency limiter. +Kinde applies two types of limiters: a **rate limiter** and a **concurrency limiter**. ### Rate limiter -The basic rate limiter restricts the number of API requests per minute as follows: +The rate limiter caps both request frequency and payload size. Key constraints: -- maximum page size of 500 per request to API GET endpoints that use the `page_size` parameter, additional results can be requested using the `page_size` and `next_token` parameters (e.g. GET `/api/v1/subscribers`) -- maximum 100 objects can be updated in a single request when sending `POST/PATCH` requests to bulk endpoints (e.g. PATCH `/api/v1/organizations/{org_code}/users`) +- **Page size:** Maximum of 500 results per request on GET endpoints that accept a `page_size` parameter. Use `page_size` and `next_token` to paginate through additional results (e.g. `GET /api/v1/subscribers`). +- **Bulk updates:** Maximum of 100 objects per request on bulk `POST`/`PATCH` endpoints (e.g. `PATCH /api/v1/organizations/{org_code}/users`). -If this affects your integrations and you require an extended period with a higher limit please get in touch. +If your integration requires a higher limit for an extended period, contact [Kinde support](https://www.kinde.com/support/). -## Common causes +### Concurrency limiter -Rate limiting can occur under a variety of conditions, but it’s most common in these scenarios: +The concurrency limiter caps the number of requests that can be in-flight at the same time. When this limit is reached, new incoming requests are shed and return a `429` response. -- Running a large volume of closely-spaced requests can lead to rate limiting. Often this is part of an analytical or migration operation. When engaging in these activities, you should try to control the request rate on the client-side. -- Issuing many long-lived requests can trigger limiting. Requests vary in the amount of Kinde’s server resources they use, and more resource-intensive requests tend to take longer and run the risk of causing new requests to be shed by the concurrency limiter. -- Resource requirements vary, but list requests and requests that include expansions generally use more resources and take longer to run. We suggest profiling the duration of Kinde API requests, and watch for timeouts to try and spot those that are unexpectedly slow. -- A sudden increase in volume like the bulk addition of new users can result in rate limiting. We try to set our rates high enough that legitimate user traffic never exceeds the limits, but if you suspect that an upcoming event might push you over the limits listed above, contact us to increase limits for you. +Resource-intensive requests — such as large list queries or requests that include expansions — consume more server resources and take longer to complete, which reduces available concurrency slots for other requests. -## Handle limiting gracefully +## What causes rate limiting? -Graceful handling involves monitoring for `429` status codes and triggering a retry method. The header `RateLimit-Reset` will return the number of seconds until the rate limit is reset. +Rate limiting most commonly occurs in these scenarios: -Your method should follow an exponential back-off schedule to reduce request volume as needed. We also recommend building randomness into the back-off schedule to avoid a ‘thundering herd’ effect. +- **High request volume.** Running a large number of closely-spaced requests — often as part of an analytical or migration operation — can trigger rate limiting. Control the request rate on the client-side when doing this. +- **Long-lived or resource-intensive requests.** Requests that consume significant server resources take longer to complete, leaving fewer concurrency slots available for new requests. +- **List requests and expansions.** These generally use more resources and run longer than other request types. Profile your Kinde API request durations and watch for unexpected timeouts. +- **Sudden traffic spikes.** Bulk operations like adding a large number of users at once can push you over the limit. If you anticipate an upcoming spike, contact Kinde support in advance to have limits increased. -Another method is to manage traffic at a global level, and throttle it back if you detect substantial rate limiting. A common technique for controlling rate is to implement something like a token bucket rate limiting algorithm on the client-side. Ready-made and mature implementations for token bucket can be found in most programming languages. +## How do I handle rate limiting gracefully? -## How M2M tokens are calculated in Kinde +When a request is rate limited, the API returns a `429` status code. The response includes a `RateLimit-Reset` header with the number of seconds until the rate limit resets: -An M2M token is generated each time you call the `/oauth2/token` Kinde API endpoint to retrieve an M2M access token. +```http +HTTP/1.1 429 Too Many Requests +RateLimit-Reset: 30 +``` -Where an access token is re-used - say where the same token is used to make another API request, this does not count as a new token. Similarly, where a token is re-used to make calls to other Kinde-registered APIs, this is also not counted as another token. +**Exponential backoff with jitter** is the recommended retry approach. Wait progressively longer between retries and add randomness to avoid a [thundering herd](https://en.wikipedia.org/wiki/Thundering_herd_problem) effect where many clients retry simultaneously: -Kinde’s free and Pro plans have a generous amount of M2M tokens included, before we start charging for them. For details, see our [pricing page](https://kinde.com/pricing/). \ No newline at end of file +```javascript +async function fetchWithBackoff(url, options, maxRetries = 5) { + for (let attempt = 0; attempt <= maxRetries; attempt++) { + const response = await fetch(url, options); + + if (response.status !== 429) return response; + if (attempt === maxRetries) throw new Error('Max retries reached'); + + const resetAfter = parseInt(response.headers.get('RateLimit-Reset') || '1', 10); + const jitter = Math.random() * 1000; + const delay = Math.max(resetAfter * 1000, Math.pow(2, attempt) * 1000) + jitter; + + await new Promise((resolve) => setTimeout(resolve, delay)); + } +} +``` + +**Token bucket (global throttle):** An alternative is to manage traffic at a global level using a [token bucket](https://en.wikipedia.org/wiki/Token_bucket) algorithm on the client-side. This lets you cap your own outbound request rate before hitting the API. Mature token bucket implementations are available in most programming languages. From 02bc8420572813a7a6a100aed902d8b5a2994f67 Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Mon, 4 May 2026 13:37:55 +0600 Subject: [PATCH 12/14] update the API troubleshooting page --- .../kinde-api/troubleshoot-kinde-api.mdx | 200 ++++++++++++++++-- 1 file changed, 184 insertions(+), 16 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/troubleshoot-kinde-api.mdx b/src/content/docs/developer-tools/kinde-api/troubleshoot-kinde-api.mdx index 22d2ca95b..12c11faa6 100644 --- a/src/content/docs/developer-tools/kinde-api/troubleshoot-kinde-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/troubleshoot-kinde-api.mdx @@ -1,54 +1,222 @@ --- page_id: 601dd8c5-6ee1-474f-ad36-201e65280462 title: Troubleshooting Kinde Management API -description: "Troubleshooting guide for common Kinde API issues including null responses and scope errors" +description: "Common errors when calling the Kinde Management API and how to fix them." sidebar: order: 10 label: "Troubleshooting" +tableOfContents: + maxHeadingLevel: 3 relatedArticles: - 51899f7f-3436-46e0-9a1b-6ecc3603a0df - 6bf993fc-a195-4836-8eaf-133812be8876 - 50284476-2442-414c-af20-01ed3ef4ca4e + - c944dcc9-35d1-4816-b2d3-a39fb0d3e68f topics: - developer-tools - kinde-api sdk: [] -languages: [] +languages: + - shell audience: - developers complexity: intermediate keywords: - troubleshooting - api errors + - 401 unauthorized + - 403 forbidden + - 429 too many requests - null response - scope errors + - invalid_client + - missing audience - token customization - custom claims -updated: 2024-01-15 + - rate limiting +updated: 2026-05-04 featured: false deprecated: false -ai_summary: Troubleshooting guide for common Kinde API issues including null responses and scope errors +ai_summary: "Troubleshooting reference for common Kinde Management API errors, grouped into three areas. Token exchange errors: a 404 Not Found caused by an incorrect domain or client ID (fix by copying values from App keys); an invalid_client error caused by wrong credentials (fix by verifying the Client ID and Client Secret); a 403 invalid_request caused by a missing or incorrect audience parameter (fix by adding the correct audience in the format https://.kinde.com/api, with a cURL example); and a 403 invalid_scope caused by a scope not being enabled on the M2M application during token exchange. API request errors: a ROUTE_NOT_FOUND error from calling a non-existent endpoint (fix by checking the Management API reference); and a SCOPE_MISSING error from calling an endpoint without the required scope enabled on the M2M application (fix by updating scopes under Settings > Applications > APIs > Manage scopes). Other errors: a null or empty response caused by missing custom claims (fix via token customization in the application settings); and a 429 Too Many Requests error from exceeding the rate or concurrency limit (handled by reading the RateLimit-Reset header and retrying with backoff — links to the API rate limits page)." --- -There's a lot of configurations and events that support API connections. Sometimes things go wrong. Here's a few common errors people come across. +If you're getting unexpected errors from the Kinde Management API, use this guide to identify the cause and apply a fix. -## When a request returns `null` +## Token exchange errors -When you request to receive data back via the API and get an unexpected or `null` response, you may need to add custom claims to the token. +### Not found -1. In Kinde, go to **Settings > Applications** and open the relevant application. -2. Select **Tokens** in the menu. -3. Scroll to the **Token customization** section. -4. Select **Customize** on the Access or ID token type and switch on / select any claims or properties you want to include in the token. +**Error response:** + +```http +HTTP/1.1 404 Not Found +``` + +**Solution:** + +Make sure you have copied the correct Kinde domain and client ID. Even if you have set up a custom domain, you must use the original Kinde domain in your request (e.g. `https://.kinde.com`). + +1. Go to **Settings > Applications** and open your M2M application. +2. Select **App keys**. +3. Copy the **Domain**, **Client ID** and **Client Secret** and update them in your request. + +### Authentication failed + +**Error response:** + +```json +{ + "error": "invalid_client", + "error_description": "Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)." +} +``` + +**Solution:** + +Verify that the **Client Secret** is copied exactly, with no typos. + +### Missing audience + +**Error response:** + +```http +HTTP/1.1 403 Forbidden +``` + +```json +{ + "error":"invalid_request", + "error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Requested audience 'https://.kinde.com/api' has not been whitelisted by the OAuth 2.0 Client." +} +``` + +**Solution:** + +Add the correct `audience` parameter to your token request. The value must be your Kinde domain followed by `/api`. Even if you use a custom domain, the `audience` value must still use your `https://.kinde.com` domain. + +To find your Kinde domain: + +1. Go to **Settings > Applications** and open your M2M application. +2. Select **Details**. +3. Copy the **Domain** value and use it in your request as follows: + +```bash +curl --request POST \ + --url 'https://.kinde.com/oauth2/token' \ + --header 'content-type: application/x-www-form-urlencoded' \ + --data grant_type=client_credentials \ + --data 'client_id=' \ + --data 'client_secret=' \ + --data 'audience=https://.kinde.com/api' +``` + +### Scope is missing + +**Error response:** + +```http +HTTP/1.1 403 Forbidden +``` + +```json +{ + "error":"invalid_scope", + "error_description":"The requested scope is invalid, unknown, or malformed. The OAuth 2.0 Client is not allowed to request scope ''." +} +``` + +**Solution:** + +Your M2M application does not have the required scope enabled for the endpoint you're calling. Add the missing scope to your application and then get a new access token before retrying. + +1. Go to **Settings > Applications** and open your M2M application. +2. Select **APIs** in the menu. +3. In the **Kinde Management API** entry, select the three dots menu and select **Manage scopes**. +4. Enable the missing scopes. 5. Select **Save**. -For more detailed information, see [Token customization](/build/tokens/token-customization/) -## Kinde Management API scope errors +For a full list of available scopes, see [API scopes](/developer-tools/kinde-api/about-m2m-scopes/). -Access to Kinde's Management API is limited by scopes. When you create or update a M2M application, you need to review and select scopes. If you find that some information is not included in a returned token, check the scopes. +## API request errors -1. In Kinde, go to **Settings > Applications** and select **View details** on the relevant M2M application. +### Route not found + +**Error response:** + +```json +{ + "errors": { + "code": "ROUTE_NOT_FOUND", + "message": "The requested API route does not exist" + } +} +``` + +**Solution:** + +The API route you're calling does not exist. Check the [Management API reference](https://kinde.com/kinde-apis/management/) for the correct endpoint path and correct any typos. + +### Scope missing error + +**Error response:** + +```json +{ + "errors": [ + { + "code": "SCOPE_MISSING", + "message": "Scope is missing: read:environments" + } + ] +} +``` + +**Solution:** + +Your M2M application does not have the required scope enabled for the endpoint you're calling. Add the missing scope to your application and then get a new access token before retrying. + +1. Go to **Settings > Applications** and open your M2M application. 2. Select **APIs** in the menu. 3. In the **Kinde Management API** entry, select the three dots menu and select **Manage scopes**. -4. Select and deselect scopes as required. +4. Enable the missing scopes. 5. Select **Save**. + +For a full list of available scopes, see [API scopes](/developer-tools/kinde-api/about-m2m-scopes/). + +## Other errors + +### API request returns null or empty + +**Solution:** + +The data you're requesting exists but isn't included in the token by default. Add custom claims to include it: + +1. Go to **Settings > Applications** and open the relevant application. +2. Select **Tokens** in the menu. +3. Scroll to the **Token customization** section. +4. Select **Customize** on the Access or ID token type and enable the claims or properties you need. +5. Select **Save**. + +For more information, see [Token customization](/build/tokens/token-customization/). + +### Too many requests + +**Error response:** + +```http +HTTP/1.1 429 Too Many Requests +RateLimit-Reset: 30 +``` + +**Solution:** + +You've exceeded the API rate or concurrency limit. Read the `RateLimit-Reset` header value to get the number of seconds before the limit resets, then wait before retrying. + +See [API rate limits](/developer-tools/kinde-api/api-rate-limits/) for a full breakdown of limits and a recommended retry strategy using exponential backoff. + +## Get support + +If you're still having problems: + +- Contact [Kinde support](https://kinde.com/support) +- See the [common error codes reference](/get-started/guides/error-codes/) \ No newline at end of file From 36c515b5b42b277a2b917b5e56c0c1283b6411fd Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Mon, 4 May 2026 14:19:04 +0600 Subject: [PATCH 13/14] fix coderabbit issues. add ai_summary --- .../kinde-api/about-m2m-scopes.mdx | 3 ++- .../kinde-api/access-token-for-api.mdx | 10 ++++++- .../kinde-api/call-the-api-postman.mdx | 4 +-- .../kinde-api/connect-to-kinde-api.mdx | 26 +++++++++++++------ .../kinde-api/search-users-via-api.mdx | 4 +-- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx b/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx index 4b591a7fa..3f0615f9a 100644 --- a/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx +++ b/src/content/docs/developer-tools/kinde-api/about-m2m-scopes.mdx @@ -57,7 +57,8 @@ The Kinde management API uses JSON Web Tokens (JWTs) to authenticate requests. T - `read:users` — read user details - `update:users` — update user details -- `read:roles` or `update:roles` — manage roles +- `read:roles` — read roles +- `update:roles` — update roles Scopes are assigned when you authorize an M2M application and can be updated at any time. Enable only what you need — fewer scopes means a smaller attack surface. diff --git a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx index 14f15cac6..4394b7ed1 100644 --- a/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/access-token-for-api.mdx @@ -334,11 +334,15 @@ dataTask.resume() { "access_token": "", // the JWT access token "expires_in": 86399, - "scope": "", // any sub scopes you defined in the request + "scope": "", // any subset of the scopes you defined in the request "token_type": "Bearer", } ``` + + The `access_token` field will contain a signed JWT for you to use in the API requests. Use the [Kinde Online JWT decoder](https://www.kinde.com/tools/online-jwt-decoder/) to decode the token. Here is the decoded M2M access token: @@ -362,6 +366,10 @@ dataTask.resume() } ``` + + ### 2. Use the access token 1. Include the access token in the `Authorization` header of your request. For example, to retrieve all users: diff --git a/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx b/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx index 1be328b97..f9a55fa0f 100644 --- a/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx +++ b/src/content/docs/developer-tools/kinde-api/call-the-api-postman.mdx @@ -117,7 +117,7 @@ We recommend that you set up a Postman environment and test this in a non-produc **Get users list from API:** 1. Create a new request. -2. In the URL field, use the `/api/v1/users` endpoint: `{{KINDE_DOMAIN}}/api/v1/users` +2. In the URL field, use the `/api/v1/users` endpoint: `https://.kinde.com/api/v1/users` 3. Go to the **Authorization** section and select **OAuth 2.0** as the Auth Type. 4. Select the **Token** from the previously saved token. 5. Select **Send**. @@ -127,7 +127,7 @@ We recommend that you set up a Postman environment and test this in a non-produc **Create a new user with API:** -1. Create a new request, set the type to **POST** and the URL to `/api/v1/user`. +1. Create a new request, set the type to **POST** and the URL to `https://.kinde.com/api/v1/user`. 2. Go to **Body**, select **raw** and enter the following JSON: ```json diff --git a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx index 2bafa5afd..c9b435a9c 100644 --- a/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/connect-to-kinde-api.mdx @@ -17,6 +17,8 @@ app_context: topics: - developer-tools - kinde-api + - authentication + - machine-to-machine sdk: [] languages: [] audience: @@ -26,18 +28,26 @@ complexity: intermediate keywords: - management api - m2m application + - machine to machine - api access - scopes - authorization - access token - - machine to machine -updated: 2026-04-30 + - client credentials + - oauth2 + - client id + - client secret + - api keys + - test token + - quickstart + - ci/cd +updated: 2026-05-04 featured: false deprecated: false -ai_summary: Step-by-step guide to setting up M2M applications and authorizing them for Kinde Management API access with proper scopes +ai_summary: "This quickstart guide walks you through connecting to the Kinde Management API using a Machine to Machine (M2M) application. The Management API provides programmatic access to everything available in the Kinde dashboard, making it ideal for CI/CD pipelines and automated account management. To get started, you create an M2M application in your Kinde dashboard and authorize it to use the Management API. You then configure the specific OAuth2 scopes your application needs — such as read:users, write:users, read:roles, and write:roles — to control what the access token can do. Once scoped, you retrieve the application's Domain, Client ID, and Client Secret from the Details page. The guide also covers how to test the API directly from the Kinde dashboard without writing code. You generate a test token for your M2M application and use it to call endpoints interactively on the Kinde Management API page, reviewing live JSON responses. For production use, tokens must be requested server-side via the OAuth2 client credentials flow. The guide links to further resources including calling the API in production, using Postman, managing Kinde configurations, and learning more about M2M scopes." --- -The Kinde Management API let's you do everything you can do with the Kinde UI. It is useful for pragmatically managing your Kinde account and resources such as use in CI/CD pipelines. +The Kinde Management API lets you do everything you can do with the Kinde UI. It is useful for programmatically managing your Kinde account and resources such as use in CI/CD pipelines. In order to call the Kinde Management API, you will need a **Machine to Machine (M2M)** access token authorized to use the Management API. @@ -50,8 +60,8 @@ This guide shows you how to set up and authorize a new M2M application with the ### 1. Create a M2M application 1. Go to your Kinde dashboard and select **Add application**. -3. Give the application a name (e.g., "API Automation"), and select **Machine to Machine** as the application type. -4. Select **Save**. +2. Give the application a name (e.g., "API Automation"), and select **Machine to Machine** as the application type. +3. Select **Save**. ### 2. Authorize the Management API @@ -71,7 +81,7 @@ This guide shows you how to set up and authorize a new M2M application with the ### 4. Get app keys -5. Go to the **Details** page and copy the app keys: +1. Go to the **Details** page and copy the app keys: - Domain - Client ID @@ -101,7 +111,7 @@ This guide shows you how to set up and authorize a new M2M application with the ![kinde management api page](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/72840d32-1f90-4fc3-30e9-40074f163f00/public) -2. Search the endpoint you want to test (e.g., roles) +2. Search for the endpoint you want to test (e.g., roles) 3. Select **Test request** in the code snippet. A pop-up will open. ![kinde management api test request](https://imagedelivery.net/skPPZTHzSlcslvHjesZQcQ/833a2c93-61ad-4fa7-8999-4b9ac4a44f00/public) diff --git a/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx b/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx index e6425c87a..0e57611b8 100644 --- a/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx @@ -114,7 +114,7 @@ GET /api/v1/search/users?query={searchterm}&properties[{key}]={value} For example, find all users from Sydney: ``` -GET /api/v1/search/users?query=*&properties[kp_user_city]=Sydney +GET /api/v1/search/users?query=*&properties[kp_usr_city]=Sydney ``` ### Filter with AND (multiple conditions) @@ -167,7 +167,7 @@ Use the `active_since` parameter to return users whose last login is on or after GET /api/v1/users?active_since=2024-01-01T00:00:00Z ``` -The `active_since` value must be an [ISO 8601 formatted date/time string](https://www.cdisc.org/kb/articles/when-would-i-use-iso8601-interval-format). +The `active_since` value must be an [ISO 8601 formatted date/time string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format). **Example response:** From 8da5a4e55dbba9ff4e3717d368e508d5ba72778c Mon Sep 17 00:00:00 2001 From: Tamal Anwar Chowdhury Date: Mon, 4 May 2026 21:38:13 +0600 Subject: [PATCH 14/14] fix the broken link in advanced user search --- .../docs/developer-tools/kinde-api/search-users-via-api.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx b/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx index 0e57611b8..afde4b756 100644 --- a/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx +++ b/src/content/docs/developer-tools/kinde-api/search-users-via-api.mdx @@ -45,7 +45,7 @@ Search and filter users via the Kinde Management API. Use this to find users wit ### What you need -- A Kinde M2M application with Management API access — see the [connect to the Kinde API guide](/developer-tools/kinde-api/connect-to-kinde-api/) +- A Kinde M2M application with Management API access, and app keys — see the [quickstart guide](/developer-tools/kinde-api/connect-to-kinde-api/) - Scope: `read:users` - A way to call the API (cURL, Postman, or the JS SDK) @@ -105,7 +105,7 @@ GET /api/v1/search/users?query=* ## Filter users by property -Append `properties[key]=value` parameters to filter by [user properties](/manage-users/user-properties/about-user-properties/). You can combine `query` with property filters. +Append `properties[key]=value` parameters to filter by [user properties](/properties/about-properties/). You can combine `query` with property filters. ``` GET /api/v1/search/users?query={searchterm}&properties[{key}]={value}