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

# Authentication

> How authentication works in Reactor

Reactor uses API keys to authenticate requests. JavaScript apps exchange the key for a short-lived
token; Python apps pass the key directly.

## Get your API key

<Steps>
  <Step title="Create an account">Sign up at [reactor.inc](https://reactor.inc).</Step>

  <Step title="Create an API key">
    Open the **[Dashboard](https://reactor.inc/dashboard)**, click your user icon, then navigate to **API Keys** to create a new key.
  </Step>

  <Step title="Copy your key">
    Your key starts with `rk_`. Store it securely and never commit it to source control.
  </Step>
</Steps>

<Tabs>
  <Tab title="JavaScript">
    ## JavaScript

    ### How it works

    Your server exchanges the API key for a short-lived token, which the browser uses to connect. Tokens
    are valid for up to 6 hours by default, or shorter if you set `expires_after`. If a token leaks, it
    expires on its own and the blast radius is limited to that token's validity window.

    <Frame>
      <img src="https://mintcdn.com/reactortechnologiesinc/oCeFlbp0H3XO2l0l/diagrams/auth-browser.svg?fit=max&auto=format&n=oCeFlbp0H3XO2l0l&q=85&s=dfd9610295acd208fe1fe6f9f0717d3f" alt="Server exchanges API key for a token, passes token to browser, browser connects to Reactor" width="660" height="224" data-path="diagrams/auth-browser.svg" />
    </Frame>

    ### Generate a token

    Exchange your API key for a short-lived token by making a `POST` request to the `/tokens` endpoint with your API key in the `Reactor-API-Key` header:

    ```typescript Default (6-hour expiry) theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
    const result = await fetch("https://api.reactor.inc/tokens", {
      method: "POST",
      headers: { "Reactor-API-Key": process.env.REACTOR_API_KEY },
    });
    const { jwt, expires_at } = await result.json();
    ```

    ```typescript Custom expiry theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
    const result = await fetch("https://api.reactor.inc/tokens", {
      method: "POST",
      headers: {
        "Reactor-API-Key": process.env.REACTOR_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ expires_after: Number(process.env.TOKEN_LIFETIME_SECONDS) }),
    });
    const { jwt, expires_at } = await result.json();
    ```

    Tokens live for **at most 6 hours**. Omit `expires_after` to get the full 6 hours; pass it (in seconds) to shorten the lifetime. Values at or above the ceiling are silently clamped.

    The server still returns 200, so always check `expires_at` (a Unix epoch timestamp) on the response to confirm the actual expiry.

    <Warning>
      Don't store your API key in client-side code. Use your server as a proxy to generate short-lived
      tokens, as shown below.
    </Warning>

    ### Server-side proxy

    Set up an API route on your server that calls the `/tokens` endpoint and returns the token to your frontend:

    <CodeGroup>
      ```typescript Next.js theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      import { NextResponse } from "next/server";

      export async function POST() {
        const result = await fetch("https://api.reactor.inc/tokens", {
          method: "POST",
          headers: { "Reactor-API-Key": process.env.REACTOR_API_KEY! },
        });
        const { jwt } = await result.json();

        return NextResponse.json({ jwt });
      }
      ```

      ```typescript Express theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
      app.post("/api/token", async (_req, res) => {
        const result = await fetch("https://api.reactor.inc/tokens", {
          method: "POST",
          headers: { "Reactor-API-Key": process.env.REACTOR_API_KEY! },
        });
        const { jwt } = await result.json();

        res.json({ jwt });
      });
      ```
    </CodeGroup>

    Then fetch the token from your frontend and pass it to the SDK:

    ```tsx app/page.tsx theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
    "use client";

    import { use } from "react";
    import { ReactorProvider, ReactorView } from "@reactor-team/js-sdk";

    async function getToken() {
      const result = await fetch("/api/token", { method: "POST" });
      const { jwt } = await result.json();
      return jwt;
    }

    const tokenPromise = getToken();

    export default function App() {
      const token = use(tokenPromise);
      return (
        <ReactorProvider modelName="your-model-name" jwtToken={token}>
          <ReactorView className="w-full aspect-video" />
        </ReactorProvider>
      );
    }
    ```

    <Note>
      If your API key is compromised, rotate it immediately from the
      **[Dashboard](https://reactor.inc/dashboard)**. Rotating does not affect active sessions. Need
      help? Join us on [Discord](https://discord.gg/tMcJM8N5N3).
    </Note>

    <Note>
      **Adopting an existing session.** If your backend creates a session and hands the `sessionId` to a
      client, the token that client connects with must belong to the same account that owns the session.
      Mint it through the same `/tokens` flow. See
      [Sessions](/concepts/sessions#multiple-connections-per-session).
    </Note>
  </Tab>

  <Tab title="Python">
    ## Python

    ### How it works

    **Python** runs server-side, so your API key goes directly to Reactor on `connect()`.

    <Frame>
      <img src="https://mintcdn.com/reactortechnologiesinc/oCeFlbp0H3XO2l0l/diagrams/auth-python.svg?fit=max&auto=format&n=oCeFlbp0H3XO2l0l&q=85&s=9376a796065bc820864391ecf93ae71d" alt="Your app sends the API key directly to Reactor" width="520" height="96" data-path="diagrams/auth-python.svg" />
    </Frame>

    Pass your API key directly to the `Reactor` constructor:

    ```python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
    import os
    from reactor_sdk import Reactor

    reactor = Reactor(
        model_name="your-model-name",
        api_key=os.environ["REACTOR_API_KEY"],
    )

    await reactor.connect()
    ```

    <Tip>
      Never hardcode `rk_...` values in your code or commit them to source control. Use environment
      variables.
    </Tip>

    <Note>Need help? Join us on [Discord](https://discord.gg/tMcJM8N5N3).</Note>
  </Tab>
</Tabs>

***
