---
title: Quickstart
description: Install the OrbitRail packages, publish your first event, and verify a signed payload.
url: https://pr-1-3b5c652a9824.thally.app/quickstart
---

# Quickstart

Install the OrbitRail packages, publish your first event, and verify a signed payload.

## Before you begin

- **Node.js 20 or later** is required by both packages
- An **OrbitRail API key** (passed via the `X-OrbitRail-Key` header)

## Install the packages

Both packages are ESM-only TypeScript libraries with zero runtime dependencies.

#### npm

    ```bash
    npm install @orbitrail/events @orbitrail/verify
    ```

#### pnpm

    ```bash
    pnpm add @orbitrail/events @orbitrail/verify
    ```

#### yarn

    ```bash
    yarn add @orbitrail/events @orbitrail/verify
    ```

## Publish your first event

Use the delivery policy constants to build a valid publish request:

```typescript
import { deliveryPolicy } from "@orbitrail/events";

const response = await fetch("https://events.orbitrail.example/v1/events", {
  method: "POST",
  headers: {
    [deliveryPolicy.authenticationHeader]: process.env.ORBITRAIL_API_KEY!,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": deliveryPolicy.requiredContentType, // "application/json"
  },
  body: JSON.stringify({
    type: "order.completed",
    payload: { orderId: "ord_12345", total: 49.99 },
  }),
});

// 202 — event accepted for delivery
console.log(response.status);
```

> **Note:**
  Every publish request requires an `Idempotency-Key` header. Reusing a key within 24 hours returns the original accepted event without creating a duplicate.

## Check delivery status

```typescript
import { deliveryPolicy, isDeliveryStatus } from "@orbitrail/events";

const eventId = "evt_abc123";
const res = await fetch(
  `https://events.orbitrail.example/v1/events/${eventId}`,
  {
    headers: {
      [deliveryPolicy.authenticationHeader]: process.env.ORBITRAIL_API_KEY!,
    },
  }
);

const { status, attempts } = await res.json();
console.log(status);  // "delivered", "retrying", "failed", etc.
console.log(isDeliveryStatus(status)); // true
```

## Verify a signed payload

On the receiving side, create a verification client and validate incoming payloads:

```typescript
import { createVerifyClient } from "@orbitrail/verify";

const client = createVerifyClient({
  apiKey: process.env.ORBITRAIL_API_KEY!,
  // Defaults: algorithm "hmac-sha256", flushLimit 100,
  // clockToleranceSeconds 60, maxSignatureAgeSeconds 300,
  // replayCacheSeconds 600
});

const isValid = await client.verify(incomingPayload);
if (!isValid) {
  throw new Error("Payload verification failed");
}
```

## What to read next

- [Delivery policy](/delivery-policy) — retry windows, timeouts, payload limits, and all policy constants
- [Publishing events](/publishing) — idempotency, content-type requirements, and error responses
- [Verify configuration](/verify-configuration) — algorithm selection, clock tolerance, signature age, and replay cache
- [API Reference](/api/introduction) — full HTTP endpoint documentation