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

# Client-side Keys

> How to create and use client-side API keys

## Create a Client-side Key

Navigate to the API Keys section of the developer console and click the "Create new key" button in the client-side keys section.

* [Staging API Keys](https://staging.crossmint.com/console/projects/apiKeys)
* [Production API Keys](https://www.crossmint.com/console/projects/apiKeys)

<Frame type="simple">
  <img src="https://mintcdn.com/crossmint/xq66q9GV6z6jjj95/images/api-reference/create-client-key.jpg?fit=max&auto=format&n=xq66q9GV6z6jjj95&q=85&s=2321e4cacd56045df299e46f3c9ea06f" alt="create client-side API key in Crossmint developer console" width="1984" height="580" data-path="images/api-reference/create-client-key.jpg" />
</Frame>

### Setting Authorized Origins

Client-side keys are exposed in the application and thus require additional security measures. The minimum requirement is to whitelist URLs that requests can be sent from. Client-side keys support two types of origins:

<Warning>
  You can only register either web origins or mobile app identifiers for a single API key, not both. If you need both
  types, you'll need to create separate API keys.
</Warning>

#### Web Origins

For web applications, you need to add the domains that requests will be sent from. In development, you'll need to add the local domain you test your application from. This is commonly `http://localhost` followed by a port number such as `3000`, `5173`, etc. For example, when developing with NextJS, the default origin you need to authorize is `http://localhost:3000`.

The expected format for web origins is a full URL with protocol, such as `https://www.yourdomain.com` or `http://localhost:3000`.

#### Mobile App Identifiers

For mobile applications, you need to add the bundle identifiers for iOS apps or package names for Android apps. The expected format is:

* iOS: Bundle ID (e.g., `com.company.appname`)
* Android: Package name (e.g., `com.company.appname`)

<Warning>
  Mobile app identifiers can be arbitrarily spoofed by malicious actors, as the headers sent from mobile applications can be modified. Do not rely solely on mobile app identifiers for security. Consider implementing additional authentication mechanisms such as JWT authentication for sensitive operations.
</Warning>

#### Desktop/CLI Applications

For desktop applications and CLI tools where origin headers cannot be reliably set, you can select the "Desktop/CLI" app type when creating your client-side API key. This option allows the key to be used without origin restrictions.

<Warning>
  **Security Warning**: Desktop/CLI keys have no origin-based protection. This means:

  * The key can be used from any origin or application
  * If the key is leaked, it can be used by anyone without restriction
  * Consider enabling JWT authentication for additional security
  * Only use this option when absolutely necessary (e.g., CLI tools, desktop apps, AI agents)

  For most use cases, we recommend using web origins or mobile app identifiers instead.
</Warning>

To create a Desktop/CLI key:

1. Select "Desktop/CLI" as the app type when creating or editing a client-side key
2. Consider enabling JWT authentication for additional security
3. Store the key securely and rotate it regularly

When you create a production API key you will need to authorize your production domain or app identifiers to use the API key. You can add multiple authorized domains or app identifiers for an API key to make requests from. Type in the domain or app identifier that you want to authorize and then click the "+ Add new origin" button.

<Frame type="simple">
  <img src="https://mintcdn.com/crossmint/xq66q9GV6z6jjj95/images/api-reference/authorized-origins.jpg?fit=max&auto=format&n=xq66q9GV6z6jjj95&q=85&s=ddc511f2bb82ed0685c83f69f6036ec8" alt="add authorized origin to API key in Crossmint developer console" width="1548" height="520" data-path="images/api-reference/authorized-origins.jpg" />
</Frame>

### Select Scopes

Within the modal that opens, toggle the required scopes you want to enable. You may need to expand an accordion for the product area you're working on to expose additional scope options.

<Frame type="simple">
  <img src="https://mintcdn.com/crossmint/xq66q9GV6z6jjj95/images/api-reference/client-scopes.jpg?fit=max&auto=format&n=xq66q9GV6z6jjj95&q=85&s=c54f3fbd934b9aeac4494d5b6503a5c1" alt="select client-side API scopes in Crossmint developer console" width="2400" height="904" data-path="images/api-reference/client-scopes.jpg" />
</Frame>

For more information on API Key scopes visit the scopes page or the API Reference.

<CardGroup cols={2}>
  <Card title="API Scopes" icon="bullseye" href="/introduction/platform/api-keys/scopes">
    Complete list of available API scopes
  </Card>

  <Card title="API Reference" icon="paper-plane" href="/api-reference/introduction">
    Detailed docs for all API endpoints
  </Card>
</CardGroup>

### JWT Authentication

Finally, select the option to require a JWT if your application or use case requires it. Enabing this setting will require that users are authenticated to permit API requests.

<Frame type="simple">
  <img src="https://mintcdn.com/crossmint/xq66q9GV6z6jjj95/images/api-reference/enable-jwt-auth.jpg?fit=max&auto=format&n=xq66q9GV6z6jjj95&q=85&s=e3ba00846c5ce631bf81f2d20d6aa1ba" alt="enable JWT Authentication in Crossmint developer console" width="1970" height="386" data-path="images/api-reference/enable-jwt-auth.jpg" />
</Frame>

<Tip>
  The [Wallets SDK](/sdk-reference/wallets/typescript/overview) requires this option to be enabled. It is optional for other
  client side APIs. For more information on the options, refer to the [JWT
  Authentication](/introduction/platform/api-keys/jwt-authentication) section.
</Tip>

If you choose to enable JWT Authentication for your client-side API key, there are additional configurations that must be made. You can choose between Crossmint authentication (ideal for staging and getting started fast), third party auth providers such as Auth0, Stytch, Firebase, Kinde, or Supabase (recommended for production), or custom solutions where you generate your own JWTs (also recommended for production).

You can find more information and guidance in the [JWT Authentication](/introduction/platform/api-keys/jwt-authentication) section.

***

## Using a Client-side Key

There are a few different approaches to using a client-side key. The most common option is passing it to the `init` function for a supported SDK. There are also some cases where you'll pass the key as a header in a raw API call from custom code, similar to how a server-side key works.

### Initializing an SDK

The most common way you'll leverage a client-side API key is by passing it to the `init` function for a supported SDK. See the examples below.

<CodeGroup>
  ```typescript crossmint-wallets-sdk.ts theme={null}
  import { CrossmintWallets, createCrossmint } from "@crossmint/wallets-sdk";

  const crossmint = createCrossmint({
  apiKey: process.env.NEXT_PUBLIC_CLIENT_SIDE_KEY ?? "",
  });

  const crossmintWallets = CrossmintWallets.from(crossmint);

  const wallet = await crossmintWallets.getOrCreateWallet({
  chain: "<your-chain>",
  signer: {
  type: "<signer-type>",
  },
  });

  ```

  ```typescript credentials-init.ts theme={null}
  import * as sdk from '@crossmint/client-sdk-verifiable-credentials';

  sdk.CrossmintAPI.init(process.env.NEXT_PUBLIC_CLIENT_SIDE_KEY);
  ```

  ```tsx auth-example.tsx theme={null}
  import { CrossmintProvider, CrossmintAuthProvider } from "@crossmint/client-sdk-react-ui";

  export default function RootLayout({
      children,
  }: Readonly<{
      children: React.ReactNode;
  }>) {
      return (
          <html lang="en">
              <body className={inter.className}>
                  <CrossmintProvider apiKey={process.env.NEXT_PUBLIC_CLIENT_SIDE_KEY ?? ""}>
                      <CrossmintAuthProvider loginMethods={["email", "google"]}>{children}</CrossmintAuthProvider>
                  </CrossmintProvider>
              </body>
          </html>
      );
  }
  ```
</CodeGroup>

### Direct API Call From Client

The Headless Checkout is one example where you may be writing custom API calls from your application to create orders. In this case, you set the client-side API key as a header named `X-API-KEY`, much like you would when making a server-side API call.

```typescript theme={null}
const createOrder = async (orderInput: any) => {
    try {
        const res = await fetch(`https://staging.crossmint.com/api/2022-06-09/orders`, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "x-api-key": process.env.NEXT_PUBLIC_CLIENT_SIDE_KEY,
            },
            body: JSON.stringify(orderInput),
        });

        const order = await res.json();

        setOrder(order.order);
        setClientSecret(order.clientSecret);
    } catch (e) {
        console.error(e);
        throw new Error("Failed to create order");
    }
};
```
