diff --git a/apps/docs/apis/introduction.mdx b/apps/docs/apis/introduction.mdx
index 5a685a15b5..5f13162ee3 100644
--- a/apps/docs/apis/introduction.mdx
+++ b/apps/docs/apis/introduction.mdx
@@ -44,22 +44,31 @@ async def main() -> None:
```
```go Golang
package main
-import (
- "fmt"
- unkey "github.com/WilfredAlmeida/unkey-go/features"
+
+import(
+ "context"
+ unkeygo "github.com/unkeyed/unkey-go"
+ "github.com/unkeyed/unkey-go/models/components"
+ "log"
)
+
func main() {
- apiKey := "key_3ZZ7faUrkfv1YAhffAcnKW74"
- response, err := unkey.KeyVerify(apiKey)
- if err != nil {
- fmt.Println("Error:", err)
- return
- }
- if response.Valid {
- fmt.Println("Key is valid")
- } else {
- fmt.Println("Key is invalid")
- }
+ ctx := context.Background()
+
+ s := unkeygo.New(
+ unkeygo.WithSecurity("UNKEY_ROOT_KEY"),
+ )
+
+ res, err := s.Keys.VerifyKey(ctx, components.V1KeysVerifyKeyRequest{
+ APIID: unkeygo.String("api_1234"),
+ Key: "sk_1234",
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ if res.V1KeysVerifyKeyResponse != nil {
+ // handle response
+ }
}
```
```bash cURL
diff --git a/apps/docs/docs.json b/apps/docs/docs.json
index 883288ee24..0f8be93178 100644
--- a/apps/docs/docs.json
+++ b/apps/docs/docs.json
@@ -315,7 +315,13 @@
"libraries/ts/sdk/keys/update",
"libraries/ts/sdk/keys/update-remaining",
"libraries/ts/sdk/keys/delete",
- "libraries/ts/sdk/keys/verifications"
+ "libraries/ts/sdk/keys/verifications",
+ "libraries/ts/sdk/keys/add-permission",
+ "libraries/ts/sdk/keys/remove-permission",
+ "libraries/ts/sdk/keys/set-permission",
+ "libraries/ts/sdk/keys/add-roles",
+ "libraries/ts/sdk/keys/remove-roles",
+ "libraries/ts/sdk/keys/set-roles"
]
},
{
@@ -327,6 +333,16 @@
"libraries/ts/sdk/apis/delete"
]
},
+ {
+ "group": "Identities",
+ "pages": [
+ "libraries/ts/sdk/identities/create-identity",
+ "libraries/ts/sdk/identities/get-identity",
+ "libraries/ts/sdk/identities/update-identity",
+ "libraries/ts/sdk/identities/list-identity",
+ "libraries/ts/sdk/identities/delete-identity"
+ ]
+ },
{
"group": "Ratelimits",
"pages": [
@@ -341,6 +357,31 @@
]
}
]
+ },
+ {
+ "group": "Migrations",
+ "pages": ["libraries/ts/sdk/migrations/migrate-to-unkey"]
+ },
+ {
+ "group": "Permissions",
+ "pages": [
+ {
+ "group": "Roles",
+ "pages": [
+ "libraries/ts/sdk/permissions/create-role",
+ "libraries/ts/sdk/permissions/get-role",
+ "libraries/ts/sdk/permissions/delete-role"
+ ]
+ },
+ {
+ "group": "Permissions",
+ "pages": [
+ "libraries/ts/sdk/permissions/create-permission",
+ "libraries/ts/sdk/permissions/get-permission",
+ "libraries/ts/sdk/permissions/delete-permission"
+ ]
+ }
+ ]
}
]
},
@@ -384,7 +425,12 @@
]
}
]
- },
+ }
+ ]
+ },
+ {
+ "group": "Community Libraries",
+ "pages": [
{
"group": "Elixir",
"pages": [
diff --git a/apps/docs/libraries/ts/sdk/apis/create.mdx b/apps/docs/libraries/ts/sdk/apis/create.mdx
index 23c1c8e55d..2b269ca5ac 100644
--- a/apps/docs/libraries/ts/sdk/apis/create.mdx
+++ b/apps/docs/libraries/ts/sdk/apis/create.mdx
@@ -3,6 +3,33 @@ title: "Create"
description: "Create a new API"
---
+
+
+```ts
+const { result, error } =await unkey.apis.create({ name: "Unkey production" });
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "apiId" : "api_123"
+ }
+}
+```
+
+
+
## Request
@@ -20,23 +47,3 @@ description: "Create a new API"
-
-
-
-```ts
-await unkey.apis.create({ name: "Unkey production" });
-```
-
-
-
-##
-
-```ts
-{
- result: {
- apiId : "api_123"
- }
-}
-```
-
-
diff --git a/apps/docs/libraries/ts/sdk/apis/delete.mdx b/apps/docs/libraries/ts/sdk/apis/delete.mdx
index 6fa85f1896..1c981f7fc1 100644
--- a/apps/docs/libraries/ts/sdk/apis/delete.mdx
+++ b/apps/docs/libraries/ts/sdk/apis/delete.mdx
@@ -3,6 +3,31 @@ title: "Delete"
description: "Permanently delete an API and revoke all keys associated with it."
---
+
+
+```ts
+const { result, error } = await unkey.apis.delete({ apiId: "api_123" });
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+```json
+{
+ "result": {}
+}
+```
+
+
+
## Request
@@ -11,13 +36,6 @@ description: "Permanently delete an API and revoke all keys associated with it."
## Response
-No response, but if no error is returned the API has been deleted successfully.
-
-
-
-```ts
-await unkey.apis.delete({ apiId: "api_123" });
-```
-
-
-
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/apis/get.mdx b/apps/docs/libraries/ts/sdk/apis/get.mdx
index 3f4290e030..f0f829fc6f 100644
--- a/apps/docs/libraries/ts/sdk/apis/get.mdx
+++ b/apps/docs/libraries/ts/sdk/apis/get.mdx
@@ -3,6 +3,38 @@ title: "Get"
description: "Retrieve the configuration of an API"
---
+
+
+```ts
+const { result, error } = await unkey.apis.get({
+ apiId: "api_123",
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "id": 'api_123',
+ "name": 'My API',
+ "workspaceId": 'ws_123'
+ }
+}
+```
+
+
+
## Request
@@ -28,28 +60,3 @@ description: "Retrieve the configuration of an API"
-
-
-
-```ts
-const api = await unkey.apis.get({
- apiId: "api_123",
-});
-
-console.log(api);
-```
-
-
-
-
-```ts
-{
- result: {
- id: 'api_123',
- name: 'My API',
- workspaceId: 'ws_123'
- }
-}
-```
-
-
diff --git a/apps/docs/libraries/ts/sdk/apis/list-keys.mdx b/apps/docs/libraries/ts/sdk/apis/list-keys.mdx
index 612d0055e4..d65d4db02e 100644
--- a/apps/docs/libraries/ts/sdk/apis/list-keys.mdx
+++ b/apps/docs/libraries/ts/sdk/apis/list-keys.mdx
@@ -3,6 +3,54 @@ title: "List Keys"
description: "Get a list of keys belonging to an API"
---
+
+
+```ts
+const { result, error } = await unkey.apis.listKeys({
+ apiId: "api_QUGih1EMtBy9eSSf3vujmF",
+ limit: 100,
+})
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result)
+```
+
+
+
+
+```json
+{
+ "result": {
+ "keys": [
+ {
+ "id": "key_HPnfviesBEKHnZBFFiY4fg",
+ "apiId": "api_QUGih1EMtBy9eSSf3vujmF",
+ "workspaceId": "ws_o17fS1LvwtRswPdncAcUM",
+ "start": "key_Crg",
+ "createdAt": 1687642066782,
+ "expires": null,
+ "ratelimit": {
+ "type": "fast",
+ "limit": 11,
+ "refillRate": 11,
+ "refillInterval": 11
+ }
+ },
+ ...
+ ],
+ "total": 4
+ }
+}
+```
+
+
+
## Request
@@ -135,43 +183,3 @@ In milliseconds
-
-
-
-```ts
-const listKeys = await unkey.apis.listKeys({
- apiId: "api_QUGih1EMtBy9eSSf3vujmF",
- limit: 100,
-})
-
-console.log(listKeys)
-
-```
-
-
-
-
-```ts
-{
- "keys": [
- {
- "id": "key_HPnfviesBEKHnZBFFiY4fg",
- "apiId": "api_QUGih1EMtBy9eSSf3vujmF",
- "workspaceId": "ws_o17fS1LvwtRswPdncAcUM",
- "start": "key_Crg",
- "createdAt": 1687642066782,
- "expires": null,
- "ratelimit": {
- "type": "fast",
- "limit": 11,
- "refillRate": 11,
- "refillInterval": 11
- }
- },
- ...
- ],
- "total": 4
-}
-```
-
-
diff --git a/apps/docs/libraries/ts/sdk/identities/create-identity.mdx b/apps/docs/libraries/ts/sdk/identities/create-identity.mdx
new file mode 100644
index 0000000000..8c61550de3
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/identities/create-identity.mdx
@@ -0,0 +1,109 @@
+---
+title: "Create An Identity"
+description: "Create a new identity in the system. This might not be necessary as newly created keys automatically create an identity if required."
+---
+
+
+
+```ts
+const { result, error } = await unkey.identities.create({
+ externalId: "user_123",
+ ratelimits: [
+ {
+ name: "tokens",
+ limit: 10,
+ duration: 1000,
+ },
+ ],
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "identityId": "id_123"
+ }
+}
+```
+
+
+
+## Request
+
+
+ The id of this identity in your system.
+
+ This usually comes from your authentication provider and could be a userId, organisationId or even an email.
+
+ It does not matter what you use, as long as it uniquely identifies something in your application.
+
+ externalIds are unique across your workspace and therefore a CONFLICT error is returned when you try to create duplicates.
+
+ Minimum length: `3`
+
+ Example: `"user_123"`
+
+
+
+This is a place for dynamic meta data, anything that feels useful for you should go here
+
+Example:
+
+```json
+{
+ "billingTier": "PRO",
+ "trialEnds": "2023-06-16T17:16:37.161Z"
+}
+```
+
+
+ Attach ratelimits to this identity.
+
+ When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits.
+
+
+
+ The name of this limit. You will need to use this again when verifying a key.
+
+ Example:`"tokens"`
+
+
+
+ How many requests may pass within a given window before requests are rejected.
+
+ Required range: `x >= 1`
+
+ Example:`10`
+
+
+
+
+ The duration for each ratelimit window in milliseconds.
+
+ Required range: `x >= 1000`
+
+ Example: `1000`
+
+
+
+## Response
+
+
+ The id of the identity. Used internally, you do not need to store this.
+
+
+ Example: `"id_123"`
+
+
diff --git a/apps/docs/libraries/ts/sdk/identities/delete-identity.mdx b/apps/docs/libraries/ts/sdk/identities/delete-identity.mdx
new file mode 100644
index 0000000000..5a5eafa393
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/identities/delete-identity.mdx
@@ -0,0 +1,42 @@
+---
+title: "Delete An Identity"
+description: "Delete an identity. This will not revoke the keys associated with the identity."
+---
+
+
+
+```ts
+const { result, error } = await unkey.identities.delete({
+ identityId: "id_1234"
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {}
+}
+```
+
+
+## Request
+
+
+ The ID of the identity you want to delete.
+
+
+## Response
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/identities/get-identity.mdx b/apps/docs/libraries/ts/sdk/identities/get-identity.mdx
new file mode 100644
index 0000000000..df05c4bcbb
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/identities/get-identity.mdx
@@ -0,0 +1,110 @@
+---
+title: "Get An Identity"
+description: "Retrieve an identity from the Unkey system"
+---
+
+
+
+```ts
+const { result, error } = await unkey.identities.get({
+ externalId: "user_123",
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "id": "id_123",
+ "externalId": "user_123",
+ "meta": {},
+ "ratelimits": [
+ {
+ "name": "tokens",
+ "limit": 10,
+ "duration": 1000
+ }
+ ]
+ }
+}
+```
+
+
+
+## Request
+
+
+ The externalId of the identity to fetch, use either identityId or externalId, if both are provided, identityId takes precedence.
+
+
+
+ The id of the identity to fetch, use either identityId or externalId, if both are provided, identityId takes precedence.
+
+
+
+## Response
+
+
+ The id of the identity. Used internally, you do not need to store this.
+ Example: `"id_123"`
+
+
+
+
+ The id in your system
+
+
+
+
+This is a place for dynamic meta data, anything that feels useful for you should go here
+
+Example:
+
+```json
+{
+ "billingTier": "PRO",
+ "trialEnds": "2023-06-16T17:16:37.161Z"
+}
+```
+
+
+ Attach ratelimits to this identity.
+
+ When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits.
+
+
+
+ The name of this limit. You will need to use this again when verifying a key.
+
+ Example:`"tokens"`
+
+
+
+ How many requests may pass within a given window before requests are rejected.
+
+ Required range: `x >= 1`
+
+ Example:`10`
+
+
+
+
+ The duration for each ratelimit window in milliseconds.
+
+ Required range: `x >= 1000`
+
+ Example: `1000`
+
+
+
diff --git a/apps/docs/libraries/ts/sdk/identities/list-identity.mdx b/apps/docs/libraries/ts/sdk/identities/list-identity.mdx
new file mode 100644
index 0000000000..fc95b716a6
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/identities/list-identity.mdx
@@ -0,0 +1,127 @@
+---
+title: "List Identities"
+description: "List all identities associated with your workspace"
+---
+
+
+
+```ts
+const { result, error } = await unkey.identities.list({
+ limit: 100
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "identities": [
+ {
+ "id": "",
+ "externalId": "",
+ "ratelimits": [
+ {
+ "name": "tokens",
+ "limit": 10,
+ "duration": 1000
+ }
+ ]
+ }
+ ],
+ "cursor": "eyJrZXkiOiJrZXlfMTIzNCJ9",
+ "total": 100
+ }
+}
+```
+
+
+
+## Request
+
+
+ This is not yet used but here for future compatibility.
+
+
+
+ The maximum number of identities to return
+
+ Required range: `1 <= x <= 100`
+
+ Example: `100`
+
+
+
+ Use this to fetch the next page of results. A new cursor will be returned in the response if there are more results.
+
+
+
+## Response
+
+
+ A list of identity objects, each containing its `id`, `externalId`, and associated `ratelimits`.
+
+
+
+ The id of the identity. Used internally, you do not need to store this.
+ Example: `"id_123"`
+
+
+
+
+ The id in your system
+
+
+
+
+ Attach ratelimits to this identity.
+
+ When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits.
+
+
+
+ The name of this limit. You will need to use this again when verifying a key.
+
+ Example:`"tokens"`
+
+
+
+ How many requests may pass within a given window before requests are rejected.
+
+ Required range: `x >= 1`
+
+ Example:`10`
+
+
+
+
+ The duration for each ratelimit window in milliseconds.
+
+ Required range: `x >= 1000`
+
+ Example: `1000`
+
+
+
+
+
+
+
+
+The total number of identities for this environment
+
+
+
+ The cursor to use for the next page of results, if no cursor is returned, there are no more results
+
+ Example:`"eyJrZXkiOiJrZXlfMTIzNCJ9"`
+
diff --git a/apps/docs/libraries/ts/sdk/identities/update-identity.mdx b/apps/docs/libraries/ts/sdk/identities/update-identity.mdx
new file mode 100644
index 0000000000..7a3eda9ed6
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/identities/update-identity.mdx
@@ -0,0 +1,174 @@
+---
+title: "Update An Identity"
+description: "Update a current identity in the system."
+---
+
+
+
+```ts
+const { result, error } = await unkey.identities.update({
+ externalId: "user_123",
+ ratelimits: [
+ {
+ name: "tokens",
+ limit: 10,
+ duration: 1000,
+ },
+ ],
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "id": "id_1234",
+ "externalId": "user_1234",
+ "meta": {
+ "stripeSubscriptionId": "sub_1234"
+ },
+ "ratelimits": [
+ {
+ "name": "tokens",
+ "limit": 10,
+ "duration": 1000
+ }
+ ]
+ }
+}
+```
+
+
+
+## Request
+
+
+ The `identityId` of the identity to update, use either `identityId` or `externalId`, if both are provided, `identityId` takes precedence.
+
+ Minimum length: `1`
+
+ Example: `"id_1234"`
+
+
+
+ The `externalId` of the identity to update, use either `identityId` or `externalId`, if both are provided, `identityId` takes precedence.
+
+ Minimum length: 1
+
+ Example: `"user_1234"`
+
+
+
+This is a place for dynamic meta data, anything that feels useful for you should go here
+
+Example:
+
+```json
+{
+ "billingTier": "PRO",
+ "trialEnds": "2023-06-16T17:16:37.161Z"
+}
+```
+
+
+ Attach ratelimits to this identity.
+
+ When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits.
+
+
+
+ The name of this limit. You will need to use this again when verifying a key.
+
+ Example:`"tokens"`
+
+
+
+ How many requests may pass within a given window before requests are rejected.
+
+ Required range: `x >= 1`
+
+ Example:`10`
+
+
+
+
+ The duration for each ratelimit window in milliseconds.
+
+ Required range: `x >= 1000`
+
+ Example: `1000`
+
+
+
+
+
+ This is not yet used but here for future compatibility.
+
+
+
+## Response
+
+
+ The id of the identity. Used internally, you do not need to store this.
+ Example: `"id_123"`
+
+
+
+
+ The id in your system
+
+
+
+
+This is a place for dynamic meta data, anything that feels useful for you should go here
+
+Example:
+
+```json
+{
+ "billingTier": "PRO",
+ "trialEnds": "2023-06-16T17:16:37.161Z"
+}
+```
+
+
+ Attach ratelimits to this identity.
+
+ When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits.
+
+
+
+ The name of this limit. You will need to use this again when verifying a key.
+
+ Example:`"tokens"`
+
+
+
+ How many requests may pass within a given window before requests are rejected.
+
+ Required range: `x >= 1`
+
+ Example:`10`
+
+
+
+
+ The duration for each ratelimit window in milliseconds.
+
+ Required range: `x >= 1000`
+
+ Example: `1000`
+
+
+
diff --git a/apps/docs/libraries/ts/sdk/keys/add-permission.mdx b/apps/docs/libraries/ts/sdk/keys/add-permission.mdx
new file mode 100644
index 0000000000..9abc4f0361
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/keys/add-permission.mdx
@@ -0,0 +1,83 @@
+---
+title: "Add Permissions"
+description: "Add one or more permissions to a key."
+---
+
+
+
+```ts
+const { result, error } = await unkey.keys.addPermissions({
+ keyId: "key_123",
+ permissions: [{
+ "name": "email.test",
+ "create": true
+ }]
+})
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result)
+
+```
+
+
+
+
+```json
+{
+ "result": [
+ {
+ "id": 'perm_45TTRKT5Yh28M6Qj',
+ "name": 'email.test'
+ }
+ ]
+}
+```
+
+
+
+To use this function, your root key must have the `rbac.*.add_permission_to_key` and the `rbac.*.create_permission` permissions if you plan on creating permissions on the fly.
+
+
+## Request
+
+
+ The id of the key
+
+
+
+ The permissions you want to add to this key
+
+
+
+The id of the permission. Provide either id or name. If both are provided id is used.
+
+
+Identify the permission via its name. Provide either id or name. If both are provided id is used.
+
+
+ Set to true to automatically create the permissions they do not exist yet. Only works when specifying name.
+ Autocreating permissions requires your root key to have the rbac.*.create_permission permission, otherwise the request will get rejected
+
+
+
+
+## Response
+
+
+
+
+
+ The id of the permission. This is used internally
+
+
+
+ The name of the permission
+
+
+
diff --git a/apps/docs/libraries/ts/sdk/keys/add-roles.mdx b/apps/docs/libraries/ts/sdk/keys/add-roles.mdx
new file mode 100644
index 0000000000..fbfb2a1aba
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/keys/add-roles.mdx
@@ -0,0 +1,83 @@
+---
+title: "Add Roles"
+description: "Add one or more roles to a key."
+---
+
+
+
+```ts
+const { result, error } = await unkey.keys.addRoles({
+ keyId: "key_123",
+ roles: [{
+ "name": "domain.manager",
+ "create": true
+ }]
+})
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result)
+
+```
+
+
+
+
+```json
+{
+ "result": [
+ {
+ "id": 'role_45TTRKT5Yh28M6Qj',
+ "name": 'domain.manager'
+ }
+ ]
+}
+```
+
+
+
+To use this function, your root key must have the rbac.*.add_role_to_key and potentially the rbac.*.create_role permissions.
+
+
+## Request
+
+
+ The id of the key
+
+
+
+ The roles you want to add to this key
+
+
+
+The id of the role. Provide either id or name. If both are provided id is used.
+
+
+Identify the role via its name. Provide either id or name. If both are provided id is used.
+
+
+ Set to true to automatically create the permissions they do not exist yet. Only works when specifying name.
+ Autocreating roles requires your root key to have the rbac.*.create_role permission, otherwise the request will get rejected
+
+
+
+
+## Response
+
+
+
+
+
+ The id of the role. This is used internally
+
+
+
+ The name of the role
+
+
+
diff --git a/apps/docs/libraries/ts/sdk/keys/create.mdx b/apps/docs/libraries/ts/sdk/keys/create.mdx
index 5c212b180d..8f7a713ad8 100644
--- a/apps/docs/libraries/ts/sdk/keys/create.mdx
+++ b/apps/docs/libraries/ts/sdk/keys/create.mdx
@@ -3,6 +3,62 @@ title: "Create"
description: "Create an api key for your users"
---
+
+
+```ts
+const { result, error } = await unkey.keys.create({
+ apiId: "api_123",
+ prefix: "xyz",
+ byteLength: 16,
+ externalId: "user_1234",
+ meta: {
+ hello: "world",
+ },
+ expires: 1686941966471,
+ ratelimit: {
+ async: true,
+ duration: 1000,
+ limit: 10,
+ },
+ remaining: 1000,
+ environment: "test",
+ name: "My Key",
+ permissions: ["email.test"],
+ roles: ["domain.manager"],
+ refill: {
+ interval: "monthly",
+ amount: 100,
+ refillDay: 15,
+ },
+ enabled: true,
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result)
+
+```
+
+
+
+
+```json
+{
+ "result": {
+ "key": "xyz_AS5HDkXXPot2MMoPHD8jnL"
+ "keyId": "key_YALWkHZaA4neUa1JJoXTAw"
+ }
+}
+```
+
+
+
+
## Request
@@ -26,12 +82,13 @@ The default is `16 bytes`, or 2128 possible combinations
-
- Your user's Id. This will provide a link between Unkey and your customer record.
-
-When validating a key, we will return this back to you, so you can clearly identify your user from their api key.
-
-
+
+ Deprecated, use externalId
+
+
+ Your user's Id. This will provide a link between Unkey and your customer record.
+ When validating a key, we will return this back to you, so you can clearly identify your user from their api key.
+
A way to easily identify the key by giving it a name.
@@ -48,6 +105,24 @@ Example:
}
```
+
+
+A list of roles that this key should have. If the role does not exist, an error is thrown
+
+Example:
+
+```
+["admin", "finance"]
+```
+
+
+A list of permissions that this key should have. If the permission does not exist, an error is thrown
+
+Example:
+
+```
+["domains.create_record", "say_hello"]
+```
You can auto expire keys by providing a unix timestamp in milliseconds.
@@ -117,11 +192,30 @@ Read more [here](/apis/features/refill)
Read more [here](/apis/features/refill)
-
+
Sets if the key is enabled or disabled.
+
+
+You may want to show keys again later. While we do not recommend this, we leave this option open for you.
+
+In addition to storing the key's hash, recoverable keys are stored in an encrypted vault, allowing you to retrieve and display the plaintext later.
+
+https://www.unkey.com/docs/security/recovering-keys for more information.
+
+
+
+Environments allow you to divide your keyspace.
+
+Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to
+give the developer a way to develop their own application without the risk of modifying real world
+resources.
+
+When you set an environment, we will return it back to you when validating the key, so you can
+handle it correctly.
+
## Response
@@ -139,47 +233,3 @@ Read more [here](/apis/features/refill)
-
-
-
-```ts
-const created = await unkey.keys.create({
- apiId:"api_7oKUUscTZy22jmVf9THxDA",
- prefix:"xyz",
- byteLength:16,
- ownerId:"chronark",
- meta:{
- hello: "world"
- },
- expires: 1686941966471,
- ratelimit: {
- type: "async",
- duration: 1000,
- limit: 10,
- },
- remaining: 1000,
- refill: {
- interval: "monthly",
- amount: 100,
- refillDay: 15,
- },
- enabled: true
-})
-
-console.log(created)
-
-```
-
-
-
-
-```ts
-{
- result: {
- key: "xyz_AS5HDkXXPot2MMoPHD8jnL"
- keyId: "key_YALWkHZaA4neUa1JJoXTAw"
- }
-}
-```
-
-
diff --git a/apps/docs/libraries/ts/sdk/keys/delete.mdx b/apps/docs/libraries/ts/sdk/keys/delete.mdx
index 7d1b298948..f16990f2d7 100644
--- a/apps/docs/libraries/ts/sdk/keys/delete.mdx
+++ b/apps/docs/libraries/ts/sdk/keys/delete.mdx
@@ -3,6 +3,30 @@ title: "Delete"
description: "Delete an api key for your users"
---
+
+
+```ts
+const { result, error } = await unkey.keys.delete({
+ keyId: "key_123",
+});
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result)
+```
+
+
+
+```json
+{
+ "result": {}
+}
+```
+
+
## Request
@@ -10,13 +34,6 @@ description: "Delete an api key for your users"
## Response
-
-No response, but if no error is returned the key has been revoked successfully.
-
-
-
-```ts
-await unkey.keys.delete({ keyId: "key_123" });
-```
-
-
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/keys/get.mdx b/apps/docs/libraries/ts/sdk/keys/get.mdx
index 17c3724248..4ec43e795c 100644
--- a/apps/docs/libraries/ts/sdk/keys/get.mdx
+++ b/apps/docs/libraries/ts/sdk/keys/get.mdx
@@ -3,6 +3,38 @@ title: "Get"
description: "Get the configuration for an api key"
---
+
+```ts
+const { result, error } = await unkey.keys.get({ keyId: "key_123" });
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result)
+```
+
+
+
+ ```json
+ {
+ "result": {
+ "id": "key_123",
+ "start": "3ZHF3",
+ "apiId": "api_123",
+ "workspaceId": "ws_123",
+ "meta": {},
+ "createdAt": 1747222842094,
+ "roles": [],
+ "permissions": [],
+ "enabled": true
+ }
+ }
+ ```
+
+
## Request
@@ -95,54 +127,52 @@ The total amount of burstable requests.
How many tokens to refill during each refillInterval.
-
-Determines the speed at which tokens are refilled, in milliseconds.
-
-
-
+
+The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit.
+
+ All roles this key belongs to
+ Example"
+ ```
+ ["admin", "finance"]
+ ```
+
+
+ All permissions this key has
-
-
-```ts
-const { result, error } = await unkey.keys.get({ keyId: "key_123" });
-```
-
-
-
-
-
-
-```ts Success
-
-const { result, error } = await unkey.keys.get({ keyId: "key_123" });
-
-if (error){
- // error will be undefined if the request was successful
-}
-
-
-// result
-{
- keyId: "key_123",
- apiId: "api_123",
- remaining: 1024,
- expires: 1630540800000,
-}
-```
-
-```ts Error
-const { result, error } = await unkey.keys.get({ keyId: "key_123" });
-
-if (error){
- console.log(error.message);
- // => "Key not found"
-}
+ Example"
+ ```
+ ["domain.dns.create_record","finance.read_receipt"]
+ ```
+
+
+Example: true
+
+
+The key in plaintext
+
-```
-
+
+ Information about the associated identity, including its `id`, `externalId`, and `meta`.
+
+
+ The id of the identity
+
+
+The external id of the identity
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/docs/libraries/ts/sdk/keys/remove-permission.mdx b/apps/docs/libraries/ts/sdk/keys/remove-permission.mdx
new file mode 100644
index 0000000000..56fd755b54
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/keys/remove-permission.mdx
@@ -0,0 +1,66 @@
+---
+title: "Remove Permissions"
+description: "Remove one or more permissions from a key."
+---
+
+
+
+
+```ts
+const { result, error } = await unkey.keys.removePermissions({
+ keyId: "key_123",
+ permissions: [
+ {
+ name: "email.test",
+ },
+ ],
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result)
+
+```
+
+
+
+
+```json
+{
+ "result": {}
+}
+```
+
+
+
+
+ To use this function, your root key must have the `rbac.*.remove_permission_from_key` permission.
+
+
+## Request
+
+
+ The id of the key
+
+
+
+ The permissions you want to remove from this key
+
+
+
+The id of the permission. Provide either id or name. If both are provided id is used.
+
+
+Identify the permission via its name. Provide either id or name. If both are provided id is used.
+
+
+
+
+## Response
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/keys/remove-roles.mdx b/apps/docs/libraries/ts/sdk/keys/remove-roles.mdx
new file mode 100644
index 0000000000..81135863c4
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/keys/remove-roles.mdx
@@ -0,0 +1,63 @@
+---
+title: "Remove Roles"
+description: "Remove one or more roles from a key."
+---
+
+
+```ts
+const { result, error } = await unkey.keys.removeRoles({
+ keyId: "key_123",
+ roles: [
+ {
+ name: "domain.manager",
+ },
+ ],
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result)
+
+```
+
+
+
+
+```json
+{ "result": {} }
+```
+
+
+
+
+ To use this function, your root key must have the `rbac.*.remove_permission_from_key` permission.
+
+
+
+## Request
+
+
+ The id of the key
+
+
+
+ The roles you want to remove from this key
+
+
+
+The id of the role. Provide either id or name. If both are provided id is used.
+
+
+Identify the role via its name. Provide either id or name. If both are provided id is used.
+
+
+
+
+## Response
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/keys/set-permission.mdx b/apps/docs/libraries/ts/sdk/keys/set-permission.mdx
new file mode 100644
index 0000000000..b6fe7cc680
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/keys/set-permission.mdx
@@ -0,0 +1,82 @@
+---
+title: "Set Permissions"
+description: "Overwrite the permissions of a key with a new set of permissions."
+---
+
+
+```ts
+const { result, error } = await unkey.keys.setPermissions({
+ keyId: "key_123",
+ permissions: [{
+ "name": "email.test",
+ "create": true
+ }]
+})
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result)
+
+```
+
+
+
+
+```json
+{
+ "result": [
+ {
+ "id": "role_45TTRKT5Yh28M6Qj",
+ "name": "domain.manager"
+ }
+ ]
+}
+```
+
+
+
+To use this function, your root key must have the `rbac.*.add_permission_to_key` and the `rbac.*.create_permission` permissions if you plan on creating permissions on the fly.
+
+
+## Request
+
+
+ The id of the key
+
+
+
+ The permissions you want to add to this key
+
+
+
+The id of the permission. Provide either id or name. If both are provided id is used.
+
+
+Identify the permission via its name. Provide either id or name. If both are provided id is used.
+
+
+ Set to true to automatically create the permissions they do not exist yet. Only works when specifying name.
+ Autocreating permissions requires your root key to have the rbac.*.create_permission permission, otherwise the request will get rejected
+
+
+
+
+## Response
+
+
+
+
+
+ The id of the permission. This is used internally
+
+
+
+ The name of the permission
+
+
+
diff --git a/apps/docs/libraries/ts/sdk/keys/set-roles.mdx b/apps/docs/libraries/ts/sdk/keys/set-roles.mdx
new file mode 100644
index 0000000000..f635afc9b6
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/keys/set-roles.mdx
@@ -0,0 +1,83 @@
+---
+title: "Set Roles"
+description: "Overwrite the roles of a key with a new set of roles."
+---
+
+
+
+```ts
+const { result, error } = await unkey.keys.setRoles({
+ keyId: "key_123",
+ roles: [{
+ "name": "domain.manager",
+ "create": true
+ }]
+})
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result)
+
+```
+
+
+
+
+```json
+{
+ "result": [
+ {
+ "id": "role_45TTRKT5Yh28M6Qj",
+ "name": "domain.manager"
+ }
+ ]
+}
+```
+
+
+
+To use this function, your root key must have the rbac.*.add_role_to_key and potentially the rbac.*.create_role permissions.
+
+
+## Request
+
+
+ The id of the key
+
+
+
+ The roles you want to add to this key
+
+
+
+The id of the role. Provide either id or name. If both are provided id is used.
+
+
+Identify the role via its name. Provide either id or name. If both are provided id is used.
+
+
+ Set to true to automatically create the permissions they do not exist yet. Only works when specifying name.
+ Autocreating roles requires your root key to have the rbac.*.create_role permission, otherwise the request will get rejected
+
+
+
+
+## Response
+
+
+
+
+
+ The id of the role. This is used internally
+
+
+
+ The name of the role
+
+
+
diff --git a/apps/docs/libraries/ts/sdk/keys/update-remaining.mdx b/apps/docs/libraries/ts/sdk/keys/update-remaining.mdx
index 29370371b5..741af9bebe 100644
--- a/apps/docs/libraries/ts/sdk/keys/update-remaining.mdx
+++ b/apps/docs/libraries/ts/sdk/keys/update-remaining.mdx
@@ -2,6 +2,35 @@
title: "Update Remaining"
description: "Update the remaining usage of a key."
---
+
+```ts
+const { result, error } =await unkey.keys.updateRemaining({
+ keyId: "xyz_AS5HDkXXPot2MMoPHD8jnL",
+ value: 300,
+ op: "set"
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result)
+```
+
+
+
+
+```json
+{
+ "result": {
+ "remaining": 300
+ }
+}
+```
+
+
## Request
@@ -26,26 +55,3 @@ description: "Update the remaining usage of a key."
-
-
-
-```ts
-await unkey.keys.updateRemaining({
- keyId: "xyz_AS5HDkXXPot2MMoPHD8jnL",
- value: 300,
- op: "set"
-});
-```
-
-
-
-
-```ts
-{
- result: {
- "remaining": 300
- }
-}
-```
-
-
diff --git a/apps/docs/libraries/ts/sdk/keys/update.mdx b/apps/docs/libraries/ts/sdk/keys/update.mdx
index 447cd7b48e..e580b2aaa5 100644
--- a/apps/docs/libraries/ts/sdk/keys/update.mdx
+++ b/apps/docs/libraries/ts/sdk/keys/update.mdx
@@ -6,6 +6,42 @@ description: "Update an api key for your users"
All json fields are optional, so you can update only the fields you need.
To delete a field, set it to `null`.
+
+
+
+```ts
+const { result, error } = await unkey.keys.update({
+ keyId: "key_1233",
+ ownerId: "new owner",
+ remaining: 300,
+ refill: {
+ interval: "monthly",
+ amount: 100,
+ refillDay: 15,
+ },
+ enabled: true
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result)
+```
+
+
+
+
+```json
+{
+ "result": {}
+}
+```
+
+
+
## Request
@@ -16,10 +52,16 @@ To delete a field, set it to `null`.
Update the name of the key.
-
+
Update the owner id of the key.
+
+ The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this back to you, so you know who is accessing your API.
+ Under the hood this upserts and connects an ìdentity for you.
+ To disconnect the key from an identity, set externalId: null.
+
+
Update the metadata of a key. You will have to provide the full metadata
object, not just the fields you want to update.
@@ -93,48 +135,29 @@ Read more [here](/apis/features/refill)
Sets if the key is enabled or disabled.
-
-## Response
-
-
-
-
-
- The updated key.
-
-
- The updated key id.
-
-
-
+
+A list of roles that this key should have. If the role does not exist, an error is thrown
-
+Example:
-```ts
-await unkey.keys.update({
- keyId: "xyz_AS5HDkXXPot2MMoPHD8jnL",
- ownerId: "new owner",
- remaining: 300,
- refil: {
- interval: "monthly",
- amount: 100,
- refillDay: 15,
- },
- enabled: true
-});
```
+["admin", "finance"]
+```
+
+
+A list of permissions that this key should have. If the permission does not exist, an error is thrown
-
+Example:
-
-```ts
-{
- result: {
- key: "xyz_AS5HDkXXPot2MMoPHD8jnL"
- keyId: "key_YALWkHZaA4neUa1JJoXTAw"
- }
-}
```
+["domains.create_record", "say_hello"]
+```
+
+
-
+## Response
+
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/keys/verifications.mdx b/apps/docs/libraries/ts/sdk/keys/verifications.mdx
index 969a052787..c2cb818636 100644
--- a/apps/docs/libraries/ts/sdk/keys/verifications.mdx
+++ b/apps/docs/libraries/ts/sdk/keys/verifications.mdx
@@ -3,6 +3,44 @@ title: "Verifications"
description: "Get usage information about your API keys"
---
+
+
+
+```ts
+const { result, error } = await unkey.keys.getVerifications({ keyId: "key_123" });
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result)
+```
+
+
+
+```json
+{
+ "verifications": [
+ {
+ "time": 1620000000000,
+ "success": 100,
+ "rateLimited": 0,
+ "usageExceeded": 0
+ },
+ {
+ "time": 1640000000000,
+ "success": 142,
+ "rateLimited": 11,
+ "usageExceeded": 20
+ },
+ ]
+}
+```
+
+
+
## Request
@@ -65,58 +103,3 @@ The number of requests that exceeded the usage limit.
-
-
-
-
-
-```ts
-const { result, error } = await unkey.keys.getVerifications({ keyId: "key_123" });
-```
-
-
-
-
-
-
-```ts Success
-
-const { result, error } = await unkey.keys.getVerifications({ keyId: "key_123" });
-
-if (error){
- // error will be undefined if the request was successful
-}
-
-
-// result
-{
- verifications: [
- {
- time: 1620000000000,
- success: 100,
- rateLimited: 0,
- usageExceeded: 0
- },
- {
- time: 1640000000000,
- success: 142,
- rateLimited: 11,
- usageExceeded: 20
- },
- // ...
- ]
-
-}
-```
-
-```ts Error
-const { result, error } = await unkey.keys.getVerifications({ keyId: "key_123" });
-
-if (error){
- console.log(error.message);
- // => "Key not found"
-}
-
-
-```
-
diff --git a/apps/docs/libraries/ts/sdk/keys/verify.mdx b/apps/docs/libraries/ts/sdk/keys/verify.mdx
index 1dfb7089a2..4a08cbd52d 100644
--- a/apps/docs/libraries/ts/sdk/keys/verify.mdx
+++ b/apps/docs/libraries/ts/sdk/keys/verify.mdx
@@ -3,7 +3,67 @@ title: "Verify"
description: "Verify a key"
---
-Verify a key from your users.
+
+```ts
+import { verifyKey } from "@unkey/api";
+
+const { result, error } = await verifyKey({ key: "key_123", apiId: "api_123" });
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+if (!result.valid) {
+ // do not grant access
+ return;
+}
+
+// process request
+console.log(result);
+```
+
+
+
+```json
+{
+ "result": {
+ "keyId": "key_1234",
+ "valid": true,
+ "name": "Customer X",
+ "ownerId": "user_123",
+ "meta": {
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "stripeCustomerId": "cus_1234"
+ },
+ "expires": 123,
+ "ratelimit": {
+ "limit": 10,
+ "remaining": 9,
+ "reset": 3600000
+ },
+ "remaining": 1000,
+ "code": "VALID",
+ "enabled": true,
+ "permissions": [
+ "dns.record.update",
+ "dns.record.delete"
+ ],
+ "environment": "test",
+ "identity": {
+ "id": "",
+ "externalId": "",
+ "meta": {}
+ }
+}
+}
+```
+
## Request
@@ -18,7 +78,7 @@ Verify a key from your users.
- Override the behavior of the ratelimit for this verification.
+ Override the behavior of the ratelimit for this verification.
The cost of this verification. This will be subtracted from the ratelimit.
@@ -107,10 +167,11 @@ Example:
checks like `IP whitelists`
- `USAGE_EXCEEDED` - The key has been used up and is no longer valid
- `RATE_LIMITED` - The verification has been blocked due to ratelimiting
- - `DISABLED` - the key is disabled
+ - `DISABLED` - The key is disabled
+ - `EXPIRED` - The key has expired
-
+
Shows if the key is enabled or disabled.
@@ -128,7 +189,7 @@ Example:
The associated identity of this key.
-
+
A free form JSON object. You can store any data you want here. As long as its properly formatted JSON.
@@ -140,69 +201,3 @@ The associated identity of this key.
-
-
-```ts
-import { verifyKey } from "@unkey/api";
-
-const { result, error } = await verifyKey({ key: "key_123", apiId: "api_123" });
-
-if (error) {
- // handle potential network or bad request error
- // a link to our docs will be in the `error.docs` field
- console.error(error.message);
- return;
-}
-
-if (!result.valid) {
- // do not grant access
- return;
-}
-
-// process request
-console.log(result);
-```
-
-
-
-
-
-```ts
-{
- result: {
- "keyId": "key_1234",
- "valid": true,
- "name": "Customer X",
- "ownerId": "user_123",
- "meta": {
- "roles": [
- "admin",
- "user"
- ],
- "stripeCustomerId": "cus_1234"
- },
- "expires": 123,
- "ratelimit": {
- "limit": 10,
- "remaining": 9,
- "reset": 3600000
- },
- "remaining": 1000,
- "code": "VALID",
- "enabled": true,
- "permissions": [
- "dns.record.update",
- "dns.record.delete"
- ],
- "environment": "test",
- "identity": {
- "id": "",
- "externalId": "",
- "meta": {}
- }
-}
-}
-
-```
-
-
diff --git a/apps/docs/libraries/ts/sdk/migrations/migrate-to-unkey.mdx b/apps/docs/libraries/ts/sdk/migrations/migrate-to-unkey.mdx
new file mode 100644
index 0000000000..9720603d43
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/migrations/migrate-to-unkey.mdx
@@ -0,0 +1,247 @@
+---
+title: "Migrate key to Unkey"
+description: "Add existing keys to unkey by specifying the key hash and other settings"
+---
+
+
+
+```ts
+const { result, error } = await unkey.migrations.createKeys([
+ {
+ apiId: "api_123",
+ prefix: "xyz",
+ byteLength: 16,
+ externalId: "user_1234",
+ plaintext: "prod_plaintext",
+ },
+ {
+ apiId: "api_123",
+ prefix: "xyz",
+ byteLength: 16,
+ externalId: "user_5678",
+ hash: {
+ value:
+ "00c0116331ffb5cc407f8f64ad58decc8b9d2e8a7b42746ba28e96ecb22b748c",
+ variant: "sha256_base64",
+ },
+ },
+]);
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "keyIds": [
+ "key_123",
+ "key_456"
+ ]
+}
+```
+
+
+
+
+## Request
+
+
+ Choose an `API` where this key should be created.
+
+
+
+To make it easier for your users to understand which product an api key belongs to, you can add prefix them.
+
+For example Stripe famously prefixes their customer ids with `cus_` or their api keys with `sk_live_`.
+
+The underscore is automtically added if you are defining a prefix, for example: `"prefix": "abc"` will result in a key like `abc_xxxxxxxxx`
+
+
+
+
+The bytelength used to generate your key determines its entropy as well as its length.
+Higher is better, but keys become longer and more annoying to handle.
+
+The default is `16 bytes`, or 2128 possible combinations
+
+
+
+
+ Deprecated, use externalId
+
+
+ Your user's Id. This will provide a link between Unkey and your customer record.
+ When validating a key, we will return this back to you, so you can clearly identify your user from their api key.
+
+
+ A way to easily identify the key by giving it a name.
+
+
+
+
+ The raw key in plaintext. If provided, unkey encrypts this value and stores it securely. Provide either hash or plaintext
+
+
+ Provide either hash or plaintext
+
+
+ The hashed and encoded key
+
+
+ The algorithm for hashing and encoding, currently only sha256 and base64 are supported
+
+ Available options: `sha256_base64`
+
+
+
+
+
+
+This is a place for dynamic meta data, anything that feels useful for you should go here
+
+Example:
+
+```json
+{
+ "billingTier": "PRO",
+ "trialEnds": "2023-06-16T17:16:37.161Z"
+}
+```
+
+
+
+A list of roles that this key should have. If the role does not exist, an error is thrown
+
+Example:
+
+```
+["admin", "finance"]
+```
+
+
+A list of permissions that this key should have. If the permission does not exist, an error is thrown
+
+Example:
+
+```
+["domains.create_record", "say_hello"]
+```
+
+
+ You can auto expire keys by providing a unix timestamp in milliseconds.
+
+Once keys expire they will automatically be deleted and are no longer valid.
+
+
+
+
+
+Unkey comes with per-key ratelimiting out of the box.
+
+
+
+
+ Either `true` (for fast rate limiting) or `false` (for consistent rate limiting).
+
+Read more [here](/apis/features/ratelimiting)
+
+
+
+ Rate limiting duration in milliseconds.
+
+
+
+ The total amount of burstable requests.
+
+
+
+ How many tokens to refill during each `refillInterval`
+
+
+ Determines the speed at which tokens are refilled.
+
+In milliseconds
+
+
+
+
+
+
+ Add how many times a key can be used, for example 100. Read more
+ [here](/apis/features/remaining)
+
+
+
+
+Unkey allows automatic refill on 'remaining' on a 'daily' or 'monthly' interval.
+
+
+
+
+ Either `daily` or `monthly`.
+
+
+
+
+
+ The amount to refill 'remaining'.
+
+Read more [here](/apis/features/refill)
+
+
+ value from `1` to `31`.
+
+ The day each month to refill 'remaining'. If no value is given, The 1st will be used as a default.
+
+Read more [here](/apis/features/refill)
+
+
+
+
+ Sets if the key is enabled or disabled.
+
+
+
+You may want to show keys again later. While we do not recommend this, we leave this option open for you.
+
+In addition to storing the key's hash, recoverable keys are stored in an encrypted vault, allowing you to retrieve and display the plaintext later.
+
+https://www.unkey.com/docs/security/recovering-keys for more information.
+
+
+
+Environments allow you to divide your keyspace.
+
+Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to
+give the developer a way to develop their own application without the risk of modifying real world
+resources.
+
+When you set an environment, we will return it back to you when validating the key, so you can
+handle it correctly.
+
+
+
+## Response
+
+
+
+
+
+ The newly created api key
+
+
+
+ A unique identifier for this key. Use it later to update or revoke the key.
+
+
+
+
diff --git a/apps/docs/libraries/ts/sdk/overview.mdx b/apps/docs/libraries/ts/sdk/overview.mdx
index 4d25998195..1c11d9b67a 100644
--- a/apps/docs/libraries/ts/sdk/overview.mdx
+++ b/apps/docs/libraries/ts/sdk/overview.mdx
@@ -4,40 +4,28 @@ description: "Typescript client for unkey"
---
-
- Currently the latest version on npm is `v2.0.0-alpha.x`, which was released on the main channel by accident.
- Due to npm's policy, we can not take it back down.
-
- v2 is coming, but it's not ready yet and lacks some api methods. Please install `@unkey/api@0.35` for now.
-
-
-
If you prefer a typed experience over calling http endpoints directly, you can use our sdk `@unkey/api`.
## Install
-
-
- ```bash
- npm install @unkey/api@0.35
+
+
+ ```bash npm
+ npm install @unkey/api
```
-
-
- ```bash
- pnpm add @unkey/api@0.35
+
+ ```bash pnpm
+ pnpm add @unkey/api
```
-
-
- ```bash
- yarn add @unkey/api@0.35
+
+ ```bash yarn
+ yarn add @unkey/api
```
-
-
- ```bash
- bun install @unkey/api@0.35
+
+ ```bash bun
+ bun install @unkey/api
```
-
-
+
## Unkey Root Key
diff --git a/apps/docs/libraries/ts/sdk/permissions/create-permission.mdx b/apps/docs/libraries/ts/sdk/permissions/create-permission.mdx
new file mode 100644
index 0000000000..b4c535b667
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/permissions/create-permission.mdx
@@ -0,0 +1,67 @@
+---
+title: "Create A Permission"
+description: "Create a new permission to use with Unkey."
+---
+
+
+
+```ts
+const { result, error } = await unkey.permissions.createPermission({
+ name: "record.write",
+ description:
+ "record.write can create new dns records for our domains.",
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "permissionId": "perm_123"
+ }
+}
+```
+
+
+
+
+To use this function, your root key must have the `rbac.*.create_permission` permission.
+
+
+## Request
+
+
+ The unique name of your permission.
+
+ Required string length: 3 - 256
+
+ Example: `"record.write"`
+
+
+
+ Explain what this permission does. This is just for your team, your users will not see this.
+
+ Required string length: 3 - 256
+
+ Example:`"record.write can create new dns records for our domains."`
+
+
+## Response
+
+
+ The id of the permission. This is used internally
+
+ Example: `"perm_123"`
+
+
diff --git a/apps/docs/libraries/ts/sdk/permissions/create-role.mdx b/apps/docs/libraries/ts/sdk/permissions/create-role.mdx
new file mode 100644
index 0000000000..4c40872a0f
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/permissions/create-role.mdx
@@ -0,0 +1,67 @@
+---
+title: "Create A Role"
+description: "Create a new role to use with Unkey"
+---
+
+
+
+```ts
+const { result, error } = await unkey.permissions.createRole({
+ name: "dns.records.manager",
+ description:
+ "dns.records.manager can read and write dns records for our domains",
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "roleId": "role_45TTRKT5Yh28M6Qj"
+ }
+}
+```
+
+
+
+
+To use this function, your root key must have the `rbac.*.create_role`
+
+
+## Request
+
+
+ The unique name of your role.
+
+ Required string length: 3 - 256
+
+ Example: `"dns.records.manager"`
+
+
+
+ Explain what this role does. This is just for your team, your users will not see this.
+
+ Required string length: 3 - 256
+
+ Example:`"dns.records.manager can read and write dns records for our domains."`
+
+
+## Response
+
+
+ The id of the role. This is used internally
+
+ Example: `"role_123"`
+
+
diff --git a/apps/docs/libraries/ts/sdk/permissions/delete-permission.mdx b/apps/docs/libraries/ts/sdk/permissions/delete-permission.mdx
new file mode 100644
index 0000000000..ace2ffea20
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/permissions/delete-permission.mdx
@@ -0,0 +1,48 @@
+---
+title: "Delete A Permission"
+description: "Delete a permission from the Unkey system"
+---
+
+
+
+```ts
+const { result, error } = await unkey.permissions.deletePermission({
+ permissionId: "perm_1234",
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {}
+}
+```
+
+
+
+
+To use this function, your root key must have the `rbac.*.delete_permission`
+
+
+## Request
+
+
+ The id of the permission to delete
+
+ Example: `"perm_123"`
+
+
+## Response
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/permissions/delete-role.mdx b/apps/docs/libraries/ts/sdk/permissions/delete-role.mdx
new file mode 100644
index 0000000000..b34e1a73fe
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/permissions/delete-role.mdx
@@ -0,0 +1,48 @@
+---
+title: "Delete A Role"
+description: "Delete a role from the Unkey system"
+---
+
+
+
+```ts
+const { result, error } = await unkey.permissions.deleteRole({
+ roleId: "role_45TTRKT5Yh28M6Qj",
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {}
+}
+```
+
+
+
+
+To use this function, your root key must have the `rbac.*.delete_role`
+
+
+## Request
+
+
+ The id of the role to delete
+
+ Example: `"role_123"`
+
+
+## Response
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/permissions/get-permission.mdx b/apps/docs/libraries/ts/sdk/permissions/get-permission.mdx
new file mode 100644
index 0000000000..b18764914b
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/permissions/get-permission.mdx
@@ -0,0 +1,70 @@
+---
+title: "Get A Permission"
+description: "Retrieve a permission from Unkey"
+---
+
+
+
+```ts
+const { result, error } = await unkey.permissions.getPermission({
+ permissionId: "perm_123",
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result);
+}
+```
+
+
+
+
+```json
+{
+ "result": {
+ "id": "perm_123",
+ "name": "domain.record.manager",
+ "description": "Can manage dns records"
+ }
+}
+```
+
+
+
+To use this function, your root key must have the `rbac.*.read_permission`
+
+
+## Request
+
+
+ The id of the permission to fetch
+
+ Minimum length: `1`
+
+ Example: `"perm_123"`
+
+
+## Response
+
+
+ The id of the permission. This is used internally
+
+ Example: `"perm_123"`
+
+
+
+
+ The unique name of your permission.
+
+ Example: `"domain.record.manager"`
+
+
+
+ The description of what this permission does. This is just for your team, your users will not see this.
+
+ Example:`"Can manage dns records."`
+
diff --git a/apps/docs/libraries/ts/sdk/permissions/get-role.mdx b/apps/docs/libraries/ts/sdk/permissions/get-role.mdx
new file mode 100644
index 0000000000..33fdc573f4
--- /dev/null
+++ b/apps/docs/libraries/ts/sdk/permissions/get-role.mdx
@@ -0,0 +1,70 @@
+---
+title: "Get A Role"
+description: "Retrieve a role from Unkey"
+---
+
+
+
+```ts
+const { result, error } = await unkey.permissions.getRole({
+ roleId: "role_45TTRKT5Yh28M6Qj",
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+console.log(result);
+```
+
+
+
+
+```json
+{
+ "result": {
+ "id": "role_45TTRKT5Yh28M6Qj",
+ "name": "domain.record.manager",
+ "description": "Can manage dns records"
+ }
+}
+```
+
+
+
+To use this function, your root key must have the `rbac.*.read_role`
+
+
+## Request
+
+
+ The id of the role to fetch
+
+ Minimum length: `1`
+
+ Example: `"role_123"`
+
+
+## Response
+
+
+ The id of the role. This is used internally
+
+ Example: `"role_123"`
+
+
+
+
+ The unique name of your role.
+
+ Example: `"dns.records.manager"`
+
+
+
+ The description of what this role does. This is just for your team, your users will not see this.
+
+
+ Example:`"dns.records.manager can read and write dns records for our domains."`
+
diff --git a/apps/docs/libraries/ts/sdk/ratelimits/limit.mdx b/apps/docs/libraries/ts/sdk/ratelimits/limit.mdx
index b5d57290b3..2f1028bd82 100644
--- a/apps/docs/libraries/ts/sdk/ratelimits/limit.mdx
+++ b/apps/docs/libraries/ts/sdk/ratelimits/limit.mdx
@@ -3,6 +3,48 @@ title: "Limit"
description: "Serverless ratelimiting"
---
+
+
+```ts
+const {result, error} = await unkey.ratelimits.limit({
+ duration: 600,
+ identifier: "userId",
+ limit: 2000,
+ namespace: "test"
+ })
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+if(!result.success){
+ console.log("This is blocked do some logic")
+ return;
+}
+
+console.log(result);
+
+```
+
+
+
+
+```json
+{
+ "result": {
+ "success": true,
+ "limit": 2000,
+ "reset": 1630000000000,
+ "remaining": 300
+ }
+}
+```
+
+
+
We have a dedicated package for ratelimiting in serverless functions. It's built with Cloudflare workers and Durable Objects to orchestrate low latency ratelimiting at the edge, without sacrificing consistency.
@@ -87,30 +129,3 @@ Unix timestamp in milliseconds when the limits are reset.
-
-
-
-```ts
-await unkey.ratelimits.limit({
- duration: 600,
- identifier: "userId",
- limit: 2000,
- namespace: "test"
- })
-```
-
-
-
-
-```ts
-{
- result: {
- "success": true,
- "limit": 2000,
- "reset": 1630000000000,
- "remaining": 300
- }
-}
-```
-
-
diff --git a/apps/docs/libraries/ts/sdk/ratelimits/overrides/delete-override.mdx b/apps/docs/libraries/ts/sdk/ratelimits/overrides/delete-override.mdx
index a8ef7b1f85..69ecaef174 100644
--- a/apps/docs/libraries/ts/sdk/ratelimits/overrides/delete-override.mdx
+++ b/apps/docs/libraries/ts/sdk/ratelimits/overrides/delete-override.mdx
@@ -3,6 +3,33 @@ title: "Delete Override"
description: "Deletes an override"
---
+
+
+```ts
+const {result,error} = await unkey.ratelimits.deleteOverride({
+ identifier: "user_123",
+ namespaceName: "email.outbound",
+})
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+ ```json
+ {
+ "result": {}
+ }
+ ```
+
+
## Request
Identifier of your user, this can be their userId, an email, an ip or anything else. Wildcards ( * ) can be used to match multiple identifiers, More info can be found at https://www.unkey.com/docs/ratelimiting/overrides#wildcard-rules
@@ -22,23 +49,6 @@ Namespaces group different limits together for better analytics. You might have
## Response
-
-No response, but if no error is returned the override has been deleted successfully.
-
-
-
-
-```ts
-await unkey.ratelimits.deleteOverride({
- identifier: "user_123",
- namespaceName: "email.outbound",
-})
-```
-```ts
-await unkey.ratelimits.deleteOverride({
- identifier: "user_123",
- namespaceId: "rlns_1234",
-})
-```
-
-
+
+ `{}`
+
diff --git a/apps/docs/libraries/ts/sdk/ratelimits/overrides/get-override.mdx b/apps/docs/libraries/ts/sdk/ratelimits/overrides/get-override.mdx
index e4455b6881..36ced387b4 100644
--- a/apps/docs/libraries/ts/sdk/ratelimits/overrides/get-override.mdx
+++ b/apps/docs/libraries/ts/sdk/ratelimits/overrides/get-override.mdx
@@ -3,6 +3,37 @@ title: "Get Override"
description: "Gets a ratelimit override"
---
+
+```ts
+const { result, error } = await unkey.ratelimits.getOverride({
+ identifier:"user.example",
+ namespaceName: "email.outbound"
+});
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+```json
+{
+ "result": {
+ "id": "rlor_4567",
+ "identifier": "user.example",
+ "limit": 10,
+ "duration": 60000,
+ "async": false
+ }
+}
+```
+
+
## Request
Identifier of your user, this can be their userId, an email, an ip or anything else. Wildcards ( * ) can be used to match multiple identifiers, More info can be found at https://www.unkey.com/docs/ratelimiting/overrides#wildcard-rules
@@ -47,33 +78,3 @@ Async will return a response immediately, lowering latency at the cost of accura
-
-
-
-```ts
-const override = await unkey.ratelimits.getOverride({
- identifier:"user.example",
- nameSpaceId:"rlns_12345",
-});
-```
-```ts
-const override = await unkey.ratelimits.getOverride({
- identifier:"user.example",
- namespaceName: "email.outbound"
-});
-```
-
-
-
-```ts
-{
- result: {
- id: "rlor_4567",
- identifier: "user.example",
- limit: 10,
- duration: 60000,
- async: false
- }
-}
-```
-
diff --git a/apps/docs/libraries/ts/sdk/ratelimits/overrides/list-overrides.mdx b/apps/docs/libraries/ts/sdk/ratelimits/overrides/list-overrides.mdx
index 290ea35dbc..887145e8ec 100644
--- a/apps/docs/libraries/ts/sdk/ratelimits/overrides/list-overrides.mdx
+++ b/apps/docs/libraries/ts/sdk/ratelimits/overrides/list-overrides.mdx
@@ -3,6 +3,45 @@ title: "List Overrides"
description: "Lists all overrides"
---
+
+
+```ts
+const { result ,error } = await unkey.ratelimits.listOverrides({
+ namespaceName: "email.outbound"
+});
+
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
+
+
+
+```json
+{
+ "result": {
+ "overrides": [
+ {
+ "id": "rlor_1234",
+ "identifier": "customer_123",
+ "limit": 10,
+ "duration": 50000,
+ "async": false
+ }
+ ],
+ total: 1,
+ cursor: 'eyJrZXkiOiJrZXlfMTIzNCJ9'
+ }
+}
+```
+
+
+
## Request
@@ -57,39 +96,3 @@ The cursor to use for pagination
-
-
-
-
-```ts
-const overrides = await unkey.ratelimits.listOverrides({
- nameSpaceId:"rlns_12345",
-});
-```
-```ts
-const overrides = await unkey.ratelimits.listOverrides({
- namespaceName: "email.outbound"
-});
-```
-
-
-
-```ts
-{
- result: {
- overrides: [
- {
- id: 'rlor_1234',
- identifier: 'customer_123',
- limit: 10,
- duration: 50000,
- async: false
- }
- ],
- total: 1,
- cursor: 'rlor_1234'
- }
-}
-```
-
-
diff --git a/apps/docs/libraries/ts/sdk/ratelimits/overrides/set-override.mdx b/apps/docs/libraries/ts/sdk/ratelimits/overrides/set-override.mdx
index 9f49c1601e..9656e950b3 100644
--- a/apps/docs/libraries/ts/sdk/ratelimits/overrides/set-override.mdx
+++ b/apps/docs/libraries/ts/sdk/ratelimits/overrides/set-override.mdx
@@ -47,31 +47,30 @@ Async will return a response immediately, lowering latency at the cost of accura
```ts
-const override = await unkey.ratelimits.setOverride({
+const { result, error } = await unkey.ratelimits.setOverride({
identifier: "user_123",
limit: 10,
duration: 60000,
namespaceId: "rlns_1234",
async: true
})
-```
-```ts
-const override = await unkey.ratelimits.setOverride({
- identifier: "user_123",
- limit: 10,
- duration: 60000,
- namespaceName: "email.outbound",
- async: true
-})
-```
+if (error) {
+ // handle potential network or bad request error
+ // a link to our docs will be in the `error.docs` field
+ console.error(error.message);
+ return;
+}
+
+console.log(result);
+```
-```ts
+```json
{
- result: {
- overrideId: 'rlor_12345'
+ "result": {
+ "overrideId": "rlor_12345"
}
}
```