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

# Credentials Overview

> Vela uses two credentials — client secrets for management and API keys for ingestion. Here is how they differ and when to use each.

## Two credential types

| Credential        | Format          | Scope         | Used for                                           |
| ----------------- | --------------- | ------------- | -------------------------------------------------- |
| **Client secret** | `vela_cs_...`   | Account-level | Creating apps, managing schemas, configuring rules |
| **API key**       | `vela_live_...` | App-level     | Ingesting events into one specific app             |

### Why two credentials?

Your **API key** is sent with every event your application ingests — it lives in your production services and travels over the network constantly. If it is ever leaked, an attacker can only ingest events into that one app. They cannot read your stored data, modify schemas, delete apps, or access anything else.

Your **client secret** has full account access. It belongs only in server-side configuration, CI/CD secret stores, or the Vela CLI. Never put a client secret in frontend JavaScript, mobile apps, or public repositories.

***

## Client secret

Used with the **Management Client** to authenticate account-level operations.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { VelaManagementClient } from '@vela-event/sdk';

  const client = new VelaManagementClient(process.env.VELA_CLIENT_SECRET!);

  const apps = await client.apps.list();
  const app = client.forApp('order-service');
  const schemas = await app.schemas.list();
  ```

  ```python Python theme={null}
  import os
  from vela import VelaManagementClient

  client = VelaManagementClient(os.environ["VELA_CLIENT_SECRET"])

  apps = client.apps.list()
  app = client.for_app("order-service")
  schemas = app.schemas.list()
  ```

  ```bash curl theme={null}
  curl https://api.velahq.xyz/v1/apps \
    -H "Authorization: Bearer vela_cs_your_secret_here"
  ```
</CodeGroup>

Generate client secrets from **Settings → Client Secrets** in the dashboard. You can have multiple active secrets simultaneously — useful for zero-downtime rotation.

***

## API key

Used with the **Ingest Client** to send events. Scoped to a single app.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { VelaIngestClient } from '@vela-event/sdk';

  const ingest = new VelaIngestClient(process.env.VELA_API_KEY!);

  await ingest.ingest({
    event: 'order.placed',
    data: { orderId: 'ord_1', amountCents: 4999 },
    level: 'info',
  });
  ```

  ```python Python theme={null}
  import os
  from vela import VelaIngestClient

  with VelaIngestClient(os.environ["VELA_API_KEY"]) as ingest:
      ingest.ingest({
          "event": "order.placed",
          "data": {"orderId": "ord_1", "amountCents": 4999},
          "level": "info",
      })
  ```

  ```bash curl theme={null}
  curl -X POST https://api.velahq.xyz/v1/ingest \
    -H "x-api-key: vela_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{ "event": "order.placed", "data": { "orderId": "ord_1" }, "level": "info" }'
  ```
</CodeGroup>

***

## Best practices

<AccordionGroup>
  <Accordion title="Use environment variables — never hardcode">
    Store credentials in environment variables or your platform's secret store.

    ```bash theme={null}
    # .env — add this to .gitignore
    VELA_CLIENT_SECRET=vela_cs_...
    VELA_API_KEY=vela_live_...
    ```

    Use `.env.sample` with empty placeholder values for documentation.
  </Accordion>

  <Accordion title="Use separate credentials per environment">
    Create a separate Vela app per environment. A leaked staging key then has zero impact on production.

    ```
    order-service-prod    → VELA_API_KEY_PROD
    order-service-staging → VELA_API_KEY_STAGING
    ```
  </Accordion>

  <Accordion title="Rotate immediately if compromised">
    * **API key** — rotate from app settings. Old key revoked instantly.
    * **Client secret** — generate a new one first, update services, then revoke the old one.
  </Accordion>

  <Accordion title="Never expose client secrets client-side">
    Client secrets grant full account access. They must never appear in browser JavaScript, mobile app bundles, Docker images pushed to public registries, or application logs.
  </Accordion>
</AccordionGroup>

<Warning>
  Credentials are shown in full only at creation time. If you lose one, revoke it and generate a new one — Vela stores only a hashed version internally.
</Warning>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Client Secrets" icon="lock" href="/credentials/client-secrets">
    Generate, use, and revoke client secrets.
  </Card>

  <Card title="API Keys" icon="key" href="/credentials/api-keys">
    How API keys are created and rotated.
  </Card>
</CardGroup>
