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

# Quickstart

> Build a complete billing loop — customer, metric, plan, subscription, and first invoice — in under 10 minutes.

This guide walks through the full Monigo billing loop from scratch using the REST API. By the end you will have a customer subscribed to a metered plan, usage events flowing in, and a draft invoice ready to inspect.

<Tip>
  Prefer to follow along in code? The Go and JavaScript SDKs each ship with a `quickstart` example that does exactly this. See the [Go SDK](/sdks/go) or [JavaScript SDK](/sdks/javascript).
</Tip>

## Prerequisites

* A Monigo account — [sign up free](https://monigo.co/register)
* Your test API key from **Dashboard → API Keys**

Use your `mk_test_...` key throughout this guide. Test mode events and invoices are fully isolated — no real charges are triggered.

***

## Step 1 — Create a customer

A customer represents one of your end-users or accounts. Every event, subscription, and invoice is attached to a customer.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.monigo.co/v1/customers \
    -H "Authorization: Bearer mk_test_..." \
    -H "Content-Type: application/json" \
    -d '{
      "external_id": "user_abc123",
      "name": "Acme Corp",
      "email": "billing@acme.com"
    }'
  ```

  ```go Go theme={null}
  customer, err := client.Customers.Create(ctx, monigo.CreateCustomerRequest{
      ExternalID: "user_abc123",
      Name:       "Acme Corp",
      Email:      "billing@acme.com",
  })
  ```

  ```ts TypeScript theme={null}
  const customer = await client.customers.create({
    external_id: 'user_abc123',
    name: 'Acme Corp',
    email: 'billing@acme.com',
  })
  ```
</CodeGroup>

Save the `id` from the response — you'll need it in later steps.

***

## Step 2 — Define a metric

A metric tells Monigo what to count and how to count it. It maps an `event_name` to an aggregation function.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.monigo.co/v1/metrics \
    -H "Authorization: Bearer mk_test_..." \
    -H "Content-Type: application/json" \
    -d '{
      "name": "API Calls",
      "event_name": "api_call",
      "aggregation": "count",
      "description": "Counts every API call made by a customer"
    }'
  ```

  ```go Go theme={null}
  metric, err := client.Metrics.Create(ctx, monigo.CreateMetricRequest{
      Name:        "API Calls",
      EventName:   "api_call",
      Aggregation: monigo.AggregationCount,
      Description: "Counts every API call made by a customer",
  })
  ```

  ```ts TypeScript theme={null}
  const metric = await client.metrics.create({
    name: 'API Calls',
    event_name: 'api_call',
    aggregation: Aggregation.Count,
    description: 'Counts every API call made by a customer',
  })
  ```
</CodeGroup>

Supported aggregations: `count`, `sum`, `max`, `minimum`, `average`, `unique`. For `sum`, `max`, `minimum`, and `average`, also set `aggregation_property` to the event property that holds the numeric value.

***

## Step 3 — Create a pricing plan

A plan defines how your metric maps to a price. Attach one or more prices when creating the plan.

This example uses flat-rate pricing — ₦2 per API call, billed monthly.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.monigo.co/v1/plans \
    -H "Authorization: Bearer mk_test_..." \
    -H "Content-Type: application/json" \
    -d '{
      "name": "API Pro",
      "description": "₦2 per API call, billed monthly",
      "currency": "NGN",
      "plan_type": "collection",
      "billing_period": "monthly",
      "prices": [
        {
          "metric_id": "<metric_id>",
          "model": "flat_unit",
          "unit_price": "2.000000"
        }
      ]
    }'
  ```

  ```go Go theme={null}
  plan, err := client.Plans.Create(ctx, monigo.CreatePlanRequest{
      Name:          "API Pro",
      Description:   "₦2 per API call, billed monthly",
      Currency:      "NGN",
      PlanType:      monigo.PlanTypeCollection,
      BillingPeriod: monigo.BillingPeriodMonthly,
      Prices: []monigo.CreatePriceRequest{
          {
              MetricID:  metric.ID,
              Model:     monigo.PricingModelFlat,
              UnitPrice: "2.000000",
          },
      },
  })
  ```

  ```ts TypeScript theme={null}
  const plan = await client.plans.create({
    name: 'API Pro',
    description: '₦2 per API call, billed monthly',
    currency: 'NGN',
    plan_type: PlanType.Collection,
    billing_period: BillingPeriod.Monthly,
    prices: [
      {
        metric_id: metric.id,
        model: PricingModel.Flat,
        unit_price: '2.000000',
      },
    ],
  })
  ```
</CodeGroup>

Monigo supports six pricing models: flat, tiered, volume, package, overage, and weighted tiered. See [Pricing Models](/guides/pricing-models) for the full reference.

***

## Step 4 — Subscribe the customer

Linking a customer to a plan starts their billing relationship. The subscription tracks the current period start and end dates.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.monigo.co/v1/subscriptions \
    -H "Authorization: Bearer mk_test_..." \
    -H "Content-Type: application/json" \
    -d '{
      "customer_id": "<customer_id>",
      "plan_id": "<plan_id>"
    }'
  ```

  ```go Go theme={null}
  sub, err := client.Subscriptions.Create(ctx, monigo.CreateSubscriptionRequest{
      CustomerID: customer.ID,
      PlanID:     plan.ID,
  })
  ```

  ```ts TypeScript theme={null}
  const sub = await client.subscriptions.create({
    customer_id: customer.id,
    plan_id: plan.id,
  })
  ```
</CodeGroup>

The subscription starts immediately and the first billing period begins now.

***

## Step 5 — Ingest usage events

Send an event every time your customer uses a billable feature. Events are aggregated into usage rollups that drive the invoice calculation.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.monigo.co/v1/ingest \
    -H "Authorization: Bearer mk_test_..." \
    -H "Content-Type: application/json" \
    -d '{
      "events": [
        {
          "event_name": "api_call",
          "customer_id": "<customer_id>",
          "idempotency_key": "req_unique_id_001",
          "timestamp": "2026-02-25T10:00:00Z",
          "properties": { "endpoint": "/v1/predict", "method": "POST" }
        },
        {
          "event_name": "api_call",
          "customer_id": "<customer_id>",
          "idempotency_key": "req_unique_id_002",
          "timestamp": "2026-02-25T10:00:05Z",
          "properties": { "endpoint": "/v1/embed", "method": "POST" }
        }
      ]
    }'
  ```

  ```go Go theme={null}
  resp, err := client.Events.Ingest(ctx, monigo.IngestRequest{
      Events: []monigo.IngestEvent{
          {
              EventName:      "api_call",
              CustomerID:     customer.ID,
              IdempotencyKey: "req_unique_id_001",
              Timestamp:      time.Now(),
              Properties:     map[string]any{"endpoint": "/v1/predict"},
          },
      },
  })
  ```

  ```ts TypeScript theme={null}
  const resp = await client.events.ingest({
    events: [
      {
        event_name: 'api_call',
        customer_id: customer.id,
        idempotency_key: 'req_unique_id_001',
        timestamp: new Date(),
        properties: { endpoint: '/v1/predict' },
      },
    ],
  })
  ```
</CodeGroup>

The `idempotency_key` ensures each event is counted exactly once even if the request is retried. You can send up to 1 000 events per batch call.

***

## Step 6 — Generate an invoice

Invoices are generated automatically at the end of each billing period, but you can also generate a draft manually at any time to preview the charge.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.monigo.co/v1/invoices/generate \
    -H "Authorization: Bearer mk_test_..." \
    -H "Content-Type: application/json" \
    -d '{ "subscription_id": "<subscription_id>" }'
  ```

  ```go Go theme={null}
  invoice, err := client.Invoices.Generate(ctx, sub.ID)
  ```

  ```ts TypeScript theme={null}
  const invoice = await client.invoices.generate(sub.id)
  ```
</CodeGroup>

The invoice will have `status: "draft"`. You can inspect the line items, finalize it to lock the amounts, and void it if needed.

***

## What happens next

You now have the complete billing loop running in test mode:

```mermaid theme={null}
flowchart TD
    A[Customer] --> B[Metric] --> C[Plan] --> D[Subscription]
    D --> E[/Events flow in/]
    E --> F[Usage rollups accumulate]
    F --> G[Invoice generated at period end]
    G --> H[Paystack / Flutterwave<br>charges customer]

    style A fill:#F3F4F6,color:#1F2937,stroke:#D1D5DB
    style B fill:#F3F4F6,color:#1F2937,stroke:#D1D5DB
    style C fill:#F3F4F6,color:#1F2937,stroke:#D1D5DB
    style D fill:#F3F4F6,color:#1F2937,stroke:#D1D5DB
    style E fill:#EFF6FF,color:#1E40AF,stroke:#3B82F6
    style F fill:#F3F4F6,color:#1F2937,stroke:#D1D5DB
    style G fill:#F3F4F6,color:#1F2937,stroke:#D1D5DB
    style H fill:#DCFCE7,color:#14532D,stroke:#16A34A
```

**Continue building:**

* [Pricing Models](/guides/pricing-models) — all six models with full code examples
* [Subscription Lifecycle](/guides/subscription-lifecycle) — pausing, canceling, reactivating
* [Invoice Lifecycle](/guides/invoice-lifecycle) — draft → finalized → paid → void
* [Connect a payment processor](/integrations/paystack) — go live with real charges
* [Idempotency & Replayability](/guides/idempotency) — correct mistakes without data loss
