# Create Consumers in a Specific Bucket

Every API key consumer in Zuplo lives inside a **bucket**. Each project's
default buckets are scoped to a specific environment, though custom buckets
created through the Developer API can be account-scoped instead. This guide
shows how to select the target environment's bucket on the **API Keys →
Consumers** page and create a consumer inside it.

:::note

For general API key management (creating consumers, viewing keys, assigning
managers), see [Manage Keys in the Portal](./api-key-administration.mdx).

:::

## Prerequisites

- A Zuplo project with at least one deployed environment (see the
  [getting started tutorial](../getting-started/gateway/setup-a-basic-gateway/index.mdx))
- The [API Key Authentication policy](../policies/api-key-inbound.mdx)
  configured on your routes
- Permission to manage API key consumers in your project

## Understanding buckets and environments

Zuplo creates three buckets for every project. Each isolates its own consumers
and keys, so a key created in one bucket only authenticates requests against the
matching environment.

| Bucket          | Environment | Git branch           |
| --------------- | ----------- | -------------------- |
| **Production**  | Production  | Default branch       |
| **Preview**     | Preview     | Non-default branches |
| **Development** | Development | Local development    |

![Diagram showing each Zuplo environment (Production, Preview, Development) mapping one-to-one to its matching bucket](../../public/media/api-key-consumer-bucket-portal-ui/bucket-environment-mapping.png)

For deeper detail, see [Buckets and Environments](./api-key-buckets.mdx).

### When you need a non-default bucket

- **Per-environment isolation.** Keep staging keys out of production.
- **Custom buckets.** Your team created extra buckets (QA, per-tenant) via the
  [Developer API](./api-key-api.mdx).
- **Shared buckets across projects.** Enterprise setups where one bucket backs
  several projects.

## Find your buckets in the portal

<Stepper>

1. Open your project in the [Zuplo Portal](https://portal.zuplo.com).

1. Navigate to the
   [**Services**](https://portal.zuplo.com/+/account/project/services) tab. It
   opens on **API Keys → Consumers** in the section sidebar.

1. Use the **Dev / Preview / Prod** switcher at the top of the sidebar to select
   the environment whose bucket you want.

1. Copy the active bucket's ID from the **Bucket ID** pill beside the
   environment badge under the **API Key Service** heading.

</Stepper>

<ModalScreenshot size="md">

![The API Keys → Consumers page with the environment switcher set to Dev and the Bucket ID pill under the API Key Service heading](../../public/media/api-key-consumer-bucket-portal-ui/services-page-dropdown.png)

</ModalScreenshot>

The **Bucket ID** pill shows the ID of the bucket that's currently active for
the selected environment. Bucket IDs start with `bckt_` — this is the value the
API Key Authentication policy's `bucketId` option takes.

## Create a consumer in a specific bucket

<Stepper>

1. On the **API Keys → Consumers** page, choose the target environment with the
   **Dev / Preview / Prod** switcher.

1. Click **Create Consumer** and fill in the form below.

1. Click **Save consumer**, then confirm it appears in the list.

</Stepper>

<ModalScreenshot size="md">

![Create new consumer modal showing Subject, Key managers, and Metadata fields plus the Save consumer button](../../public/media/api-key-consumer-bucket-portal-ui/create-consumer-modal.png)

</ModalScreenshot>

### Consumer form fields

| Field            | Required | Runtime value       | Notes                                                                                                                       |
| ---------------- | -------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **Subject**      | Yes      | `request.user.sub`  | Unique within the bucket. Identifies the consumer in logs and policy code.                                                  |
| **Key managers** | No       | n/a                 | Comma-separated emails of users who can manage this consumer's keys via the [Developer Portal](../dev-portal/overview.mdx). |
| **Metadata**     | No       | `request.user.data` | Valid JSON object. Plan info, customer IDs, anything your policies need at runtime.                                         |

:::tip

Once created, the consumer's API key only authenticates requests routed through
an environment whose API Key Authentication policy resolves to that same bucket.

:::

## How bucket selection affects key validation

The [API Key Authentication policy](../policies/api-key-inbound.mdx) decides
which bucket to validate keys against. With no bucket set, the policy defaults
to the bucket that matches the current environment:

| Environment | Default bucket |
| ----------- | -------------- |
| Production  | Production     |
| Preview     | Preview        |
| Development | Development    |

For a custom bucket, set `bucketId` on the policy so it checks the right one:

```json
{
  "export": "ApiKeyInboundPolicy",
  "module": "$import(@zuplo/runtime)",
  "options": {
    "bucketId": "bckt_2HaK3odRyJle6NJSu8mzNKBC30BYxllxL",
    "allowUnauthenticatedRequests": false
  }
}
```

The policy's `bucketName` option is deprecated. Policies that set it keep
working, but the runtime logs a warning — use `bucketId` instead.

:::caution

If the consumer lives in one bucket but the policy checks a different bucket,
the key is not found and the request returns `401 Unauthorized`. Make sure the
policy's bucket matches the bucket where you created the consumer.

:::

## Using the Developer API instead

To script consumer creation as part of an onboarding flow or CI/CD pipeline, use
the [Zuplo Developer API](./api-key-api.mdx):

```bash
curl \
  https://dev.zuplo.com/v1/accounts/$ACCOUNT_NAME/key-buckets/$BUCKET_ID/consumers?with-api-key=true \
  --request POST \
  --header "Content-type: application/json" \
  --header "Authorization: Bearer $ZAPI_KEY" \
  --data '{
    "name": "my-consumer",
    "description": "Created via API",
    "metadata": { "plan": "gold" }
  }'
```

Replace `$ACCOUNT_NAME` with your Zuplo account name, `$BUCKET_ID` with the
target bucket's ID, and `$ZAPI_KEY` with your
[Zuplo API key](./accounts/zuplo-api-keys.mdx). The bucket name also works here,
but it's deprecated. For more information, see
[Bucket identifiers](./api-key-buckets.mdx#bucket-identifiers). Full reference
at the [Developer API documentation](https://dev.zuplo.com/docs).

## Troubleshooting

<details>
<summary>My API key returns 401 Unauthorized</summary>

Usually a bucket mismatch. The consumer is in one bucket, but the policy checks
a different one.

1. In the portal, open **Services → API Keys → Consumers** and confirm which
   bucket holds the consumer.
2. Open the route's API Key Authentication policy. If `bucketId` (or the
   deprecated `bucketName`) is set, verify it matches the consumer's bucket. If
   neither is set, the policy uses the current environment's default bucket.
3. Either recreate the consumer in the correct bucket, or update the policy's
   `bucketId` to match.

</details>

<details>
<summary>I don't see the bucket I'm looking for</summary>

- **Environment.** Switch the **Dev / Preview / Prod** toggle to the environment
  whose bucket you're looking for.
- **Custom buckets.** Buckets created via the Developer API are account-scoped,
  not environment-scoped, so the sidebar's environment switcher doesn't surface
  them. Confirm they exist with the
  [list buckets API endpoint](https://dev.zuplo.com/docs) and manage them
  through the API.
- **Permissions.** Account-level roles control access to the Services section.
  Confirm your role can view and manage API key consumers.

</details>

<details>
<summary>I created a consumer but it doesn't appear in the expected environment</summary>

Consumers belong to buckets, not environments directly. A consumer created while
viewing the **Preview** environment sits in the preview bucket and only
authenticates preview environments. Switch the **Dev / Preview / Prod** toggle
to the matching environment to locate it.

</details>

## Related documentation

- [Buckets and Environments](./api-key-buckets.mdx): How buckets map to
  environments
- [Manage Keys in the Portal](./api-key-administration.mdx): General portal
  management walkthrough
- [API Key Authentication policy](../policies/api-key-inbound.mdx): Policy
  configuration reference including `bucketId`
- [Use the Developer API](./api-key-api.mdx): Programmatic consumer management
- [Create an API Key Consumer on Login](../dev-portal/dev-portal-create-consumer-on-auth.mdx):
  Automatically create consumers when users sign in
- [Environments](./environments.mdx): How environments work in Zuplo
