> ## 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.

# API Keys

> App-level credentials used exclusively for event ingestion. One active key per app, shown once at creation.

## What is an API key?

An API key (`vela_live_...`) is the credential your application uses when calling `POST /v1/ingest`. It is scoped to a **single app** — it can only ingest events into that app and has no access to any management endpoints.

This scope is intentional. Your API key lives in production services and is sent with every event. Even if it is compromised, the worst case is fake events being ingested — an attacker cannot read data, modify schemas, or access other apps.

## Format

```
vela_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

## How API keys are created

An API key is generated automatically when you create an app. The **full key is shown once** — at creation time only.

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

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

  const { app, apiKey } = await client.apps.create({ name: 'Order Service' });

  console.log(app.slug); // "order-service"
  console.log(apiKey);   // "vela_live_..." — save this immediately
  ```

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

  client = VelaManagementClient(os.environ["VELA_CLIENT_SECRET"])
  result = client.apps.create({"name": "Order Service"})

  print(result.app.slug)  # "order-service"
  print(result.api_key)   # "vela_live_..." — save this immediately
  ```

  ```bash curl theme={null}
  curl -X POST https://api.velahq.xyz/v1/apps \
    -H "Authorization: Bearer vela_cs_..." \
    -H "Content-Type: application/json" \
    -d '{ "name": "Order Service" }'
  ```
</CodeGroup>

<Warning>
  The full API key is returned only at creation and during rotation. Store it in your secret manager immediately — Vela stores only a hashed version and cannot recover the original.
</Warning>

## Using an API key

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

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

  // Single event
  const result = await ingest.ingest({
    event: 'order.placed',
    data: { orderId: 'ord_abc123', amountCents: 4999, currency: 'USD' },
    level: 'info',
    customer_id: 'cust_42',
  });

  console.log(result.accepted);     // 1
  console.log(result.events[0].id); // "evt_01j9..."

  // Batch — up to 100 events per request
  const batch = await ingest.ingest([
    { event: 'order.placed',   data: { orderId: 'ord_1', amountCents: 1999 }, level: 'info' },
    { event: 'payment.failed', data: { orderId: 'ord_2', reason: 'card_declined' }, level: 'error' },
  ]);

  console.log(batch.accepted); // 2
  ```

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

  with VelaIngestClient(os.environ["VELA_API_KEY"]) as ingest:
      result = ingest.ingest({
          "event": "order.placed",
          "data": {"orderId": "ord_abc123", "amountCents": 4999},
          "level": "info",
      })
      print(result.accepted)      # 1
      print(result.events[0].id)  # "evt_01j9..."
  ```

  ```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_abc123", "amountCents": 4999 },
      "level": "info"
    }'
  ```
</CodeGroup>

## Rotating an API key

Rotate a key if it is compromised or as part of regular security hygiene. The old key is **revoked instantly** on rotation.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const { app, apiKey } = await client.apps.rotateKey('order-service');

  console.log(apiKey); // new key — update your services now
  // Previous key is immediately invalid
  ```

  ```python Python theme={null}
  result = client.apps.rotate_key("order-service")
  print(result.api_key)  # new key
  # Previous key is immediately invalid
  ```

  ```bash curl theme={null}
  curl -X POST https://api.velahq.xyz/v1/apps/order-service/rotate-key \
    -H "Authorization: Bearer vela_cs_..."
  ```
</CodeGroup>

<Note>
  Rotation is instant and irreversible. If multiple services share an API key, update all of them. A brief window of `401 Unauthorized` errors is expected between rotation and deployment.
</Note>

## Viewing existing apps

The full key value is not shown after creation. You can list apps and see masked hints:

```typescript theme={null}
const apps = await client.apps.list();
for (const app of apps) {
  console.log(`${app.name} — ${app.apiKeyHint}`);
  // "Order Service — vela_live_abc1..."
}
```

If you need the full key, rotate it to receive a new one.
