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

# Quick Start

> From zero to a recurring subscription with automatic recovery in five requests.

This walks the happy path of the public API. Every call here has a live playground in the [API Reference](/api-reference/introduction) — you can run them from the page with a test key.

<Note>
  All examples use **test mode**. Test and live are physically separate database schemas; a `sk_test_` key can never touch live data. See [Modes](/api-reference/modes).
</Note>

## 1. Authenticate

Every merchant request carries a secret API key as a bearer token. The key prefix selects the mode.

```bash theme={null}
export DURO_KEY="sk_test_•••••••••••••••••••"
export DURO_API="https://api.useduro.com"
```

## 2. Create a plan

A plan is the thing customers subscribe to: an amount, an interval, and optional recovery knobs (`trialDays`, `maxCycles`).

```bash theme={null}
curl -s $DURO_API/v1/plans \
  -H "Authorization: Bearer $DURO_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pro Monthly",
    "amount": 500000,
    "currency": "NGN",
    "interval": "month",
    "intervalCount": 1,
    "trialDays": 0
  }'
```

<Note>Amounts are in **minor units** (kobo). `500000` = ₦5,000.00. Intervals: `hour`, `day`, `week`, `month`, `quarter`, `biannual`, `year`.</Note>

## 3. Create a customer

```bash theme={null}
curl -s $DURO_API/v1/customers \
  -H "Authorization: Bearer $DURO_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email": "ada@example.com", "phone": "2348012345678", "merchantRef": "EXT-001" }'
```

`merchantRef` is your own ID for this customer — you can later look them up by it (`GET /v1/customers/ref/EXT-001`) and fetch their transactions without ever storing a Duro ID.

## 4. Subscribe them

```bash theme={null}
curl -s $DURO_API/v1/subscriptions \
  -H "Authorization: Bearer $DURO_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "customerId": "cus_•••", "planId": "plan_•••" }'
```

The subscription is now live. When `currentPeriodEnd` passes, the [billing worker](/billing/renewal-engine) picks it up automatically: it generates an invoice, charges the gateway, and either advances the period (success) or hands the failure to the [recovery engine](/billing/dunning).

## 5. Listen for what happens

You don't poll. You subscribe to events. **Webhook endpoints are configured in the dashboard** (Developers → Webhooks) — add your URL, pick the events, and copy the signing secret (shown once). Duro then delivers signed, retried events for the whole lifecycle to your server.

<Steps>
  <Step title="Add an endpoint in the dashboard">
    Developers → Webhooks → Add endpoint. Enter your `https://` URL and choose the events to receive (e.g. `subscription_payment_success`, `subscription_payment_failed`, `subscription_payment_recovered`).
  </Step>

  <Step title="Store the signing secret">
    Shown once on creation. You'll use it to verify the `Duro-Signature` header on every delivery.
  </Step>

  <Step title="Verify and handle">
    Recompute the HMAC and compare in constant time — see [Webhook events](/api-reference/webhook-events).
  </Step>
</Steps>

## The whole loop, on a timeline

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant You as Your server
    participant API as public-api
    participant W as billing-worker
    participant GW as Gateway
    participant H as Your webhook

    You->>API: POST /v1/subscriptions
    API-->>You: 201 active
    Note over W: ...period ends...
    W->>W: scan finds due subscription
    W->>GW: charge renewal
    alt success
        GW-->>W: succeeded
        W->>W: advance period, +1 cycle
        W->>H: subscription_payment_success
    else failure
        GW-->>W: failed (insufficient_funds)
        W->>W: schedule retry (payday-aware)
        W->>H: subscription_payment_failed
        Note over W: ...retries on the right rail...
        W->>H: subscription_payment_recovered
    end
```

That's the entire product in one diagram. The rest of these docs explain every arrow.

<CardGroup cols={2}>
  <Card title="Inline checkout instead" icon="window" href="/payments/inline-sdk">
    Don't want to manage subscriptions server-side? Drop in `duro.pay()` and let the popup do identity, payment, and tokenisation.
  </Card>

  <Card title="Full API reference" icon="terminal" href="/api-reference/introduction">
    Interactive playground for every endpoint, with auth, pagination, idempotency, and the event catalog.
  </Card>
</CardGroup>
