Register and manage APIs
Manage your APIs
You must be on the Kinde Plus plan and higher to use custom API scopes.
Kinde lets you add custom scopes to help manage access to your APIs. Scopes define token permissions used by your APIs, and provide a reliable way to control access to your API resources.
You need to have registered your APIs in Kinde to secure them using scopes.
Note that this topic is NOT about adding custom scopes for the Kinde Management API, it is only related to adding custom scopes to your own APIs. For information about Kinde Management API scopes, see this topic.
read or write, you can create scopes tailored to different levels of access, such as read:userprofile or write:roles.read:user_status or write:mobilephone.If your API is already described in an OpenAPI 3.x or Swagger 2 specification, you can upload the file to Kinde and automatically generate scopes from your API operations — instead of adding each scope manually.
You need a registered custom API (not the Kinde Management API) and the API scopes feature enabled for your plan.
.json, .yaml, or .yml file that contains a valid OpenAPI 3.x or Swagger 2 document with a paths object. (Maximum file size: 20MB)
Your file will be uploaded.Kinde parses the file and creates one scope per supported HTTP operation in the spec. When the import finishes, the generated scopes appear on the Scopes tab. Scopes imported from OpenAPI are labeled with an OpenAPI badge.
Kinde creates a scope for each HTTP operation (GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD, and TRACE) defined under paths in your spec.
Each scope name follows this pattern:
{method}:{normalized_path}For example, these operations:
| OpenAPI path | HTTP method | Generated scope |
|---|---|---|
/users/{userId} | GET | get:users_userid |
/users/{userId} | POST | post:users_userid |
/health | GET | get:health |
Kinde builds the scope name by:
{ and } from path parameters (for example, {userId} becomes userid)/ with _If a generated scope name would exceed 64 characters, Kinde shortens it and appends a stable hash suffix so scope names stay unique.
The scope description is taken from the operation’s summary field when present. If there is no summary, Kinde uses operationId, or falls back to the HTTP method and path (for example, GET /users/{userId}).
Reserved scope names (such as openid, profile, and offline_access) are skipped and not imported.
After your first upload, the OpenAPI spec page shows:
Select View logs on any history entry to see a report of scopes that were created, skipped as duplicates, or removed during that import.
To sync scopes with an updated API definition, upload a new file from the OpenAPI spec page.
When you upload a replacement file:
You need permission to delete API scopes to replace an existing import.
To remove an OpenAPI import and all scopes generated from it:
This removes only scopes that were generated from that import. Scopes you added manually on the Scopes tab are not affected.
Generated scopes behave like manually created scopes. You can authorize them for applications, assign them to API keys, and request them in token calls.
On the Scopes tab, scopes imported from OpenAPI show an OpenAPI badge. You cannot edit or delete individual generated scopes from the Scopes tab — update them by uploading a new spec, or remove them by deleting the import on the OpenAPI spec page.
| Action | Permissions |
|---|---|
| View the OpenAPI spec page | read:apis |
| Upload a spec (first import) | create:api_scopes, update:apis |
| Replace an existing import | create:api_scopes, update:apis, delete:api_scopes |
| Delete an import | update:apis, delete:api_scopes |
Take care deleting scopes. If a scope is in use, it can cause breaking changes for users and applications that are dependent on them.
By default, token requests for an authorized application will return all the scopes enabled in the section above. However, 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 for your API, or because you want your users to be very specific in their requests.
Example request:
curl --request POST \ --url 'https://<your_subdomain>.kinde.com/oauth2/token' \ --header 'content-type: application/x-www-form-urlencoded' \ --data grant_type=client_credentials \ --data 'client_id=<your_m2m_client_id>' \ --data 'client_secret=<your_m2m_client_secret>' \ --data 'audience=<your_api_audience>' \ --data 'scope=join:competitions update:competitions'If you manage access to your APIs using API keys, you can set scopes for the API keys, giving you more granular control over access, depending on who has the keys.