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

# Quickstart

> Send your first event to Vela in under 5 minutes

## Prerequisites

* A running Vela instance — [self-host locally](https://github.com/vela-event/vela#getting-started) or use the cloud
* A **client secret** (`vela_cs_...`) — to manage schemas and rules
* An **API key** (`vela_live_...`) — to ingest events

Both credentials are generated from the dashboard. See the [credentials guide](/credentials/overview).

## Step 1: Install the SDK

<CodeGroup>
  ```bash npm theme={null}
  npm install @vela-event/sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @vela-event/sdk
  ```

  ```bash pip theme={null}
  pip install vela-sdk
  ```
</CodeGroup>

## Step 2: Set credentials as environment variables

Never hardcode credentials in your source files.

```bash theme={null}
export VELA_CLIENT_SECRET="vela_cs_..."
export VELA_API_KEY="vela_live_..."
```

For local dev, put these in a `.env` file and load with `dotenv`.

## Step 3: Register an event schema

Schemas tell Vela the exact shape of each event type. An event without a matching schema is rejected at ingest time with a `400` error.

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

  const client = new VelaManagementClient(process.env.VELA_CLIENT_SECRET!);
  const app = client.forApp('your-app-slug');

  await app.schemas.create({
    eventName: 'order.placed',
    description: 'Fired when a customer completes checkout',
    fields: [
      { id: 'f1', name: 'orderId',      type: 'string', required: true  },
      { id: 'f2', name: 'amountCents',  type: 'number', required: true  },
      { id: 'f3', name: 'currency',     type: 'enum',   required: true,
        enumValues: ['USD', 'EUR', 'GBP'] },
      { id: 'f4', name: 'customerEmail',type: 'string', required: false },
    ],
  });

  console.log('Schema registered.');
  ```

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

  client = VelaManagementClient(os.environ["VELA_CLIENT_SECRET"])
  app = client.for_app("your-app-slug")

  app.schemas.create({
      "event_name": "order.placed",
      "description": "Fired when a customer completes checkout",
      "fields": [
          {"id": "f1", "name": "orderId",       "type": "string", "required": True},
          {"id": "f2", "name": "amountCents",   "type": "number", "required": True},
          {"id": "f3", "name": "currency",      "type": "enum",   "required": True,
           "enum_values": ["USD", "EUR", "GBP"]},
          {"id": "f4", "name": "customerEmail", "type": "string", "required": False},
      ],
  })

  print("Schema registered.")
  ```

  ```bash CLI theme={null}
  cat > vela/schemas/order.placed.json << 'EOF'
  {
    "eventName": "order.placed",
    "description": "Fired when a customer completes checkout",
    "fields": [
      { "id": "f1", "name": "orderId",       "type": "string", "required": true },
      { "id": "f2", "name": "amountCents",   "type": "number", "required": true },
      { "id": "f3", "name": "currency",      "type": "enum",   "required": true,
        "enumValues": ["USD", "EUR", "GBP"] },
      { "id": "f4", "name": "customerEmail", "type": "string", "required": false }
    ]
  }
  EOF

  vela push
  # ✓ Created order.placed
  ```
</CodeGroup>

## Step 4: Send your first event

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

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

  const result = await ingest.ingest({
    event: 'order.placed',
    data: {
      orderId: 'ord_abc123',
      amountCents: 4999,
      currency: 'USD',
      customerEmail: 'jane@example.com',
    },
    level: 'info',
  });

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

  ```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,
              "currency": "USD",
              "customerEmail": "jane@example.com",
          },
          "level": "info",
      })
      print(result.accepted)      # 1
      print(result.events[0].id)  # evt_01j9...
  ```

  ```bash curl theme={null}
  curl -X POST http://localhost:3000/v1/ingest \
    -H "x-api-key: vela_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "event": "order.placed",
      "data": {
        "orderId": "ord_abc123",
        "amountCents": 4999,
        "currency": "USD"
      },
      "level": "info"
    }'
  ```
</CodeGroup>

A successful ingest returns `201`:

```json theme={null}
{
  "accepted": 1,
  "events": [
    { "id": "evt_01j9...", "eventName": "order.placed", "createdAt": "2024-06-01T12:00:00Z" }
  ]
}
```

If a required field is missing, you get `400`:

```json theme={null}
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Event validation failed: field 'amountCents' is required"
}
```

## Step 5: Create a notification rule (optional)

Notification rules decide what events trigger alerts and where they go. Destinations (Slack, Discord, Email) are configured in the dashboard first — then referenced by ID in the rule.

<CodeGroup>
  ```typescript TypeScript theme={null}
  await app.notificationRules.create({
    name: 'Alert on high-value orders',
    eventName: 'order.placed',
    conditions: [
      { field: 'amountCents', operator: 'gt', value: 10000 },
    ],
    actions: [
      {
        id: 'action-slack',
        destinationId: 'dest-uuid-from-dashboard',
        channel: 'slack',
        enabled: true,
      },
    ],
  });
  ```

  ```python Python theme={null}
  app.notification_rules.create({
      "name": "Alert on high-value orders",
      "event_name": "order.placed",
      "conditions": [
          {"field": "amountCents", "operator": "gt", "value": 10000},
      ],
      "actions": [
          {
              "id": "action-slack",
              "destination_id": "dest-uuid-from-dashboard",
              "channel": "slack",
              "enabled": True,
          },
      ],
  })
  ```
</CodeGroup>

Now every `order.placed` event with `amountCents > 10000` will post a Slack message automatically — with retries and a dead-letter queue built in.

## What's next

<CardGroup cols={2}>
  <Card title="Core Concepts" icon="lightbulb" href="/concepts">
    Understand apps, schemas, events, and rules in depth.
  </Card>

  <Card title="TypeScript SDK" icon="js" href="/sdks/typescript/overview">
    Batch ingestion, error handling, all resource methods.
  </Card>

  <Card title="CLI" icon="terminal" href="/cli/overview">
    Manage schemas as code with diff, push, and pull.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Direct HTTP API docs with request/response examples.
  </Card>
</CardGroup>
