> ## Documentation Index
> Fetch the complete documentation index at: https://unkey.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Shared Rate Limits

> Create your first identity in Unkey and attach shared rate limits across multiple API keys. Group keys by user, team, or organization.

This quickstart will guide you through creating your first identity with shared ratelimits and a key that is connected to the identity.

The examples use curl and the TypeScript SDK. You can use any language or library to make requests to the Unkey API.

### Requirements

You will need your api id and root key to make requests to the Unkey API. You can find these in the Unkey dashboard.

<CodeGroup>
  ```bash cURL theme={"theme":"kanagawa-wave"}
  export UNKEY_ROOT_KEY="unkey_XXX"
  ```

  ```typescript TypeScript theme={"theme":"kanagawa-wave"}
  // Install with: npm install @unkey/api
  import { Unkey } from "@unkey/api";

  const apiId = "api_XXX";
  const unkey = new Unkey({ rootKey: "unkey_XXX" });
  ```
</CodeGroup>

The root key requires the following permissions:

```ts theme={"theme":"kanagawa-wave"}
"identity.*.create_identity";
"identity.*.read_identity";
"identity.*.update_identity";
"api.*.create_key";
"api.*.verify_key";
```

### Create an Identity

To create an identity, you need to make a request to the `/v2/identities.createIdentity` endpoint. You can specify an `externalId` and `meta` object to store additional information about the identity.

Unkey does not care what the `externalId` is, but it must be unique for each identity. Commonly used are user or organization ids. The `meta` object can be used to store any additional information you want to associate with the identity.

<CodeGroup>
  ```bash cURL theme={"theme":"kanagawa-wave"}
  curl --fail-with-body \
    https://api.unkey.com/v2/identities.createIdentity \
    -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "externalId": "user_1234abc",
      "meta": {
        "stripeCustomerId": "cus_123"
      }
    }'
  ```

  ```typescript TypeScript theme={"theme":"kanagawa-wave"}
  const externalId = "user_1234abc";

  const { data: createdIdentity } =
    await unkey.identities.createIdentity({
      externalId,
      meta: {
        stripeCustomerId: "cus_123",
      },
    });
  ```
</CodeGroup>

### Retrieve an Identity

Let's retrieve the identity to make sure it got created successfully:

<CodeGroup>
  ```bash cURL theme={"theme":"kanagawa-wave"}
  # Replace IDENTITY_ID with data.identityId from the create response.
  curl --fail-with-body \
    https://api.unkey.com/v2/identities.getIdentity \
    -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "identity": "IDENTITY_ID"
    }'
  ```

  ```typescript TypeScript theme={"theme":"kanagawa-wave"}
  const { data: identity } = await unkey.identities.getIdentity({
    identity: createdIdentity.identityId,
  });

  console.log(identity);
  ```
</CodeGroup>

### Create a Key

Let's create a key and connect it to the identity:

<CodeGroup>
  ```bash cURL theme={"theme":"kanagawa-wave"}
  curl --fail-with-body \
    https://api.unkey.com/v2/keys.createKey \
    -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "apiId": "api_XXX",
      "prefix": "acme",
      "externalId": "user_1234abc"
    }'
  ```

  ```typescript TypeScript theme={"theme":"kanagawa-wave"}
  const { data: key } = await unkey.keys.createKey({
    apiId,
    prefix: "acme",
    externalId,
  });
  ```
</CodeGroup>

### Verify the Key

When you verify the key, you will receive the identity that the key is connected to and can act accordingly in your API handler.

<CodeGroup>
  ```bash cURL theme={"theme":"kanagawa-wave"}
  # Replace API_KEY with data.key from the create key response.
  curl --fail-with-body \
    https://api.unkey.com/v2/keys.verifyKey \
    -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "key": "API_KEY"
    }'
  ```

  ```typescript TypeScript theme={"theme":"kanagawa-wave"}
  const { data: verified } = await unkey.keys.verifyKey({
    key: key.key,
  });

  if (!verified.valid) {
    throw new Error(`Key verification failed: ${verified.code}`);
  }

  console.log(verified.identity);
  ```
</CodeGroup>

### Ratelimits

Ratelimits can be set on the identity level. Ratelimits set on the identity level are shared across all keys connected to the identity.

<CodeGroup>
  ```bash cURL theme={"theme":"kanagawa-wave"}
  curl --fail-with-body \
    https://api.unkey.com/v2/identities.updateIdentity \
    -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "identity": "IDENTITY_ID",
      "ratelimits": [
        {
          "name": "requests",
          "limit": 10,
          "duration": 86400000
        },
        {
          "name": "tokens",
          "limit": 1000,
          "duration": 60000
        }
      ]
    }'
  ```

  ```typescript TypeScript theme={"theme":"kanagawa-wave"}
  await unkey.identities.updateIdentity({
    identity: createdIdentity.identityId,
    ratelimits: [
      {
        name: "requests",
        limit: 10,
        duration: 24 * 60 * 60 * 1000,
      },
      {
        name: "tokens",
        limit: 1000,
        duration: 60 * 1000,
      },
    ],
  });
  ```
</CodeGroup>

### Verify the Key with Ratelimits

Now let's verify the key again and specify the limits

In this case, we pretend like a user is requesting to use 200 tokens. We specify the `requests` ratelimit to enforce a limit of 10 requests per day and the `tokens` ratelimit to enforce a limit of 1000 tokens per minute. Additionally we specify the cost of the tokens to be 200.

<CodeGroup>
  ```bash cURL theme={"theme":"kanagawa-wave"}
  curl --fail-with-body \
    https://api.unkey.com/v2/keys.verifyKey \
    -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "key": "API_KEY",
      "ratelimits": [
        {
          "name": "requests",
          "cost": 1
        },
        {
          "name": "tokens",
          "cost": 200
        }
      ]
    }'
  ```

  ```typescript TypeScript theme={"theme":"kanagawa-wave"}
  const { data: limited } = await unkey.keys.verifyKey({
    key: key.key,
    ratelimits: [
      { name: "requests", cost: 1 },
      { name: "tokens", cost: 200 },
    ],
  });

  if (!limited.valid) {
    throw new Error(`Key verification failed: ${limited.code}`);
  }

  console.log(limited.identity);
  ```
</CodeGroup>

That's it, you have successfully created an identity and key with shared ratelimits. You can now use the key to verify requests and enforce ratelimits in your API handler.
