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

# Authentication

> Get started in under a minute with Node.js or Python SDKs, or use raw HTTP. Create API keys, exchange credentials for Bearer tokens, and authenticate requests.

The Dealroom API supports two types of API keys:

* **Programmatic (M2M) keys** — for server-side integrations using the OAuth2 client credentials grant. Each key has a `client_id` and `client_secret`.
* **Browser app (application) keys** — for single-page apps (SPAs) using Authorization Code + PKCE. No `client_secret`; read-only permissions only.

## Creating an API key

You can create API keys from the Dealroom dashboard or the API. Pick the type that fits your use case.

### From the Dealroom dashboard

Go to [**Settings > API**](https://app-next.dealroom.co/settings/api) in your Dealroom dashboard:

<Frame>
  <img src="https://mintcdn.com/dealroomco-prod/tgO8oPtzcgpJ0q-w/mintlify/getting-started/settings-api.png?fit=max&auto=format&n=tgO8oPtzcgpJ0q-w&q=85&s=18fdd355501640cf90e6e184b58d8889" alt="Dealroom API Keys settings page" width="2494" height="724" data-path="mintlify/getting-started/settings-api.png" />
</Frame>

1. Choose the key type: **Programmatic** for server-side, **Browser app** for browser SPAs.
2. Enter a descriptive name (e.g. `Production — Data Pipeline`).
3. Click **+ Create key**.
4. For Programmatic (M2M) keys: copy the `client_id` and `client_secret` immediately — the secret is shown only once.
   For application keys: copy the `client_id` — there is no secret in the SPA flow.

## Quick start

Install the dependencies for your language and start making API calls in under a minute.
The SDKs handle token exchange, caching, and automatic refresh — you just provide your credentials.

<CodeGroup>
  ```typescript Node.js theme={null}
  import { ClientCredentials } from "simple-oauth2";
  import axios from "axios";

  const CLIENT_ID = process.env.DEALROOM_CLIENT_ID;
  const CLIENT_SECRET = process.env.DEALROOM_CLIENT_SECRET;

  // Set up OAuth2 client credentials
  const oauth = new ClientCredentials({
    client: { id: CLIENT_ID, secret: CLIENT_SECRET },
    auth: {
      tokenHost: "https://accounts.dealroom.co",
      tokenPath: "/oauth/token",
    },
  });

  // Create an axios instance with required headers
  const dealroom = axios.create({
    baseURL: "https://api-next.dealroom.co/api",
    headers: {
      "X-Client-Id": CLIENT_ID,
    },
  });

  // Auto-refresh token before every request
  let token = await oauth.getToken({ audience: "https://api-next.dealroom.co" });

  dealroom.interceptors.request.use(async (config) => {
    if (token.expired()) {
      token = await oauth.getToken({ audience: "https://api-next.dealroom.co" });
    }
    config.headers.Authorization = `Bearer ${token.token.access_token}`;
    return config;
  });

  // Make requests — token handling is automatic
  const { data } = await dealroom.get("/entities", {
    params: { limit: 10, sort: "-launch_date" },
  });
  console.log(data);
  ```

  ```python Python theme={null}
  import os
  from authlib.integrations.requests_client import OAuth2Session

  CLIENT_ID = os.environ["DEALROOM_CLIENT_ID"]
  CLIENT_SECRET = os.environ["DEALROOM_CLIENT_SECRET"]

  # Set up OAuth2 client credentials — token refresh is automatic
  session = OAuth2Session(
      client_id=CLIENT_ID,
      client_secret=CLIENT_SECRET,
      token_endpoint="https://accounts.dealroom.co/oauth/token",
  )
  session.headers.update({
      "X-Client-Id": CLIENT_ID,
  })
  session.fetch_token(
      url="https://accounts.dealroom.co/oauth/token",
      grant_type="client_credentials",
      audience="https://api-next.dealroom.co",
  )

  # Make requests — token handling is automatic
  response = session.get(
      "https://api-next.dealroom.co/api/data/entities",
      params={"limit": 10, "sort": "-launch_date"},
  )
  print(response.json())
  ```

  ```bash cURL theme={null}
  # Step 1: Get a token
  ACCESS_TOKEN=$(curl -s -X POST "https://accounts.dealroom.co/oauth/token" \
    -H "Content-Type: application/json" \
    -d '{
      "client_id": "YOUR_CLIENT_ID",
      "client_secret": "YOUR_CLIENT_SECRET",
      "audience": "https://api-next.dealroom.co",
      "grant_type": "client_credentials"
    }' | jq -r '.access_token')

  # Step 2: Make requests
  curl "https://api-next.dealroom.co/api/data/entities?limit=10&sort=-launch_date" \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H "X-Client-Id: YOUR_CLIENT_ID"
  ```
</CodeGroup>

<AccordionGroup>
  <Accordion title="Node.js setup">
    ```bash theme={null}
    npm install simple-oauth2 axios
    ```
  </Accordion>

  <Accordion title="Python setup">
    ```bash theme={null}
    pip install authlib requests
    ```
  </Accordion>
</AccordionGroup>

## Obtaining a Bearer token

If you prefer to handle token management yourself, exchange your credentials at the Auth0 token endpoint:

```bash theme={null}
curl -X POST https://accounts.dealroom.co/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://api-next.dealroom.co",
    "grant_type": "client_credentials"
  }'
```

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 86400
}
```

Tokens are valid for `expires_in` seconds (typically 24h). **Cache and reuse them.** Requesting
a new token per API call is unnecessary and adds latency.

## Making authenticated requests

Every request **must** include two headers:

| Header          | Description                                         | Example                          |
| --------------- | --------------------------------------------------- | -------------------------------- |
| `Authorization` | Bearer token from the token endpoint                | `Bearer eyJhbGciOiJSUzI1NiIs...` |
| `X-Client-Id`   | The `client_id` issued when the API key was created | `abc123def456`                   |

```bash theme={null}
curl "https://api-next.dealroom.co/api/data/entities?limit=10&sort=-launch_date" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "X-Client-Id: YOUR_CLIENT_ID"
```

### Why two headers?

* **`Authorization`** — authenticates the request via JWT.
* **`X-Client-Id`** — cross-checked against the token's `sub` claim as an extra authenticity
  guard. Must match the `client_id` used to obtain the token.

## Error responses

Missing or invalid headers return **400 Bad Request**:

```json theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "X-Client-Id header is required for API key requests"
  }
}
```

## Permissions

API keys support fine-grained scopes. You can only grant permissions that you already hold.
Common permissions:

| Permission          | Description                    |
| ------------------- | ------------------------------ |
| `read:entities`     | Query companies, funds, people |
| `read:investors`    | Query investor profiles        |
| `read:founders`     | Query founder profiles         |
| `read:transactions` | Query funding rounds           |
| `read:valuations`   | Query company valuations       |

## Usage dashboard

After making API requests, the dashboard **Settings > API** page shows:

* **Total requests** — aggregated request count over time
* **Endpoint breakdown** — which endpoints are being called and how often
* **Last used** — when each key was last active

Usage data may take up to 60 seconds to appear after requests are made.

## Best practices

* **Principle of least privilege** — only grant permissions your integration needs.
* **Rotate regularly** — revoke and recreate API keys periodically.
* **Never commit secrets** — use environment variables or a secrets manager.
* **Cache tokens** — reuse the access token for its full lifetime before refreshing.
