Orb

Orb Subscriptions API

Create, fetch, list, update, and cancel subscriptions, schedule and unschedule plan changes, redeem coupons, adjust price intervals and quantities, and read subscription usage, costs, and schedules.

OpenAPI Specification

orb-billing-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Orb API
  description: >-
    Orb is a usage-based billing and metering platform. The REST API ingests
    timestamped usage events, models customers, plans, prices, items, and
    billable metrics, manages subscriptions, and automates invoicing, credit
    ledgers, coupons, alerts, and webhooks. All endpoints are served over HTTPS
    at https://api.withorb.com/v1 and authenticated with a Bearer API key.
  termsOfService: https://www.withorb.com/legal/terms-of-service
  contact:
    name: Orb Support
    url: https://www.withorb.com
    email: team@withorb.com
  version: '1.0'
servers:
  - url: https://api.withorb.com/v1
    description: Orb production API
security:
  - bearerAuth: []
tags:
  - name: Customers
  - name: Plans
  - name: Subscriptions
  - name: Events
  - name: Metrics
  - name: Invoices
  - name: Credits
  - name: Prices
  - name: Items
  - name: Coupons
  - name: Alerts
paths:
  /customers:
    get:
      operationId: listCustomers
      tags:
        - Customers
      summary: List customers
      description: Returns a paginated list of customers, ordered by descending creation time.
      parameters:
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of customers.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerList'
        '401':
          $ref: '#/components/responses/Unauthorized'
    post:
      operationId: createCustomer
      tags:
        - Customers
      summary: Create customer
      description: Creates a new customer, optionally with an external_customer_id alias.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerCreate'
      responses:
        '201':
          description: The newly created customer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /customers/{customer_id}:
    parameters:
      - $ref: '#/components/parameters/CustomerId'
    get:
      operationId: fetchCustomer
      tags:
        - Customers
      summary: Fetch customer
      responses:
        '200':
          description: The requested customer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      operationId: updateCustomer
      tags:
        - Customers
      summary: Update customer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerUpdate'
      responses:
        '200':
          description: The updated customer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      operationId: deleteCustomer
      tags:
        - Customers
      summary: Delete customer
      description: Permanently deletes a customer. This operation is irreversible.
      responses:
        '204':
          description: The customer was deleted.
        '404':
          $ref: '#/components/responses/NotFound'
  /customers/external_customer_id/{external_customer_id}:
    parameters:
      - $ref: '#/components/parameters/ExternalCustomerId'
    get:
      operationId: fetchCustomerByExternalId
      tags:
        - Customers
      summary: Fetch customer by external ID
      responses:
        '200':
          description: The requested customer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '404':
          $ref: '#/components/responses/NotFound'
  /customers/{customer_id}/costs:
    parameters:
      - $ref: '#/components/parameters/CustomerId'
    get:
      operationId: fetchCustomerCosts
      tags:
        - Customers
      summary: Fetch customer costs
      description: Returns the cost breakdown for a customer over a time range.
      parameters:
        - name: timeframe_start
          in: query
          schema:
            type: string
            format: date-time
        - name: timeframe_end
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: The customer's cost breakdown.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CostList'
  /customers/{customer_id}/portal_sessions:
    parameters:
      - $ref: '#/components/parameters/CustomerId'
    post:
      operationId: createPortalSession
      tags:
        - Customers
      summary: Create portal session
      description: Creates a hosted customer portal session URL for the customer.
      responses:
        '201':
          description: A portal session with a URL the customer can visit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PortalSession'
  /plans:
    get:
      operationId: listPlans
      tags:
        - Plans
      summary: List plans
      parameters:
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of plans.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlanList'
    post:
      operationId: createPlan
      tags:
        - Plans
      summary: Create plan
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlanCreate'
      responses:
        '201':
          description: The newly created plan.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Plan'
  /plans/{plan_id}:
    parameters:
      - name: plan_id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: fetchPlan
      tags:
        - Plans
      summary: Fetch plan
      responses:
        '200':
          description: The requested plan.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Plan'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      operationId: updatePlan
      tags:
        - Plans
      summary: Update plan
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                metadata:
                  type: object
                  additionalProperties:
                    type: string
                external_plan_id:
                  type: string
      responses:
        '200':
          description: The updated plan.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Plan'
  /subscriptions:
    get:
      operationId: listSubscriptions
      tags:
        - Subscriptions
      summary: List subscriptions
      parameters:
        - name: customer_id
          in: query
          schema:
            type: string
        - name: external_customer_id
          in: query
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: string
            enum:
              - active
              - ended
              - upcoming
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of subscriptions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionList'
    post:
      operationId: createSubscription
      tags:
        - Subscriptions
      summary: Create subscription
      description: >-
        Creates a subscription that associates a customer with a plan, starting
        the accrual of usage charges into a draft invoice.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscriptionCreate'
      responses:
        '201':
          description: The newly created subscription.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
        '400':
          $ref: '#/components/responses/BadRequest'
  /subscriptions/{subscription_id}:
    parameters:
      - name: subscription_id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: fetchSubscription
      tags:
        - Subscriptions
      summary: Fetch subscription
      responses:
        '200':
          description: The requested subscription.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      operationId: updateSubscription
      tags:
        - Subscriptions
      summary: Update subscription
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                metadata:
                  type: object
                  additionalProperties:
                    type: string
      responses:
        '200':
          description: The updated subscription.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
  /subscriptions/{subscription_id}/cancel:
    parameters:
      - name: subscription_id
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: cancelSubscription
      tags:
        - Subscriptions
      summary: Cancel subscription
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - cancel_option
              properties:
                cancel_option:
                  type: string
                  enum:
                    - end_of_subscription_term
                    - immediate
                    - requested_date
                cancellation_date:
                  type: string
                  format: date-time
      responses:
        '200':
          description: The canceled subscription.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
  /subscriptions/{subscription_id}/usage:
    parameters:
      - name: subscription_id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: fetchSubscriptionUsage
      tags:
        - Subscriptions
      summary: Fetch subscription usage
      description: Returns usage quantities for the subscription's billable metrics over a window.
      parameters:
        - name: timeframe_start
          in: query
          schema:
            type: string
            format: date-time
        - name: timeframe_end
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: The subscription usage breakdown.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionUsage'
  /subscriptions/{subscription_id}/schedule_plan_change:
    parameters:
      - name: subscription_id
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: schedulePlanChange
      tags:
        - Subscriptions
      summary: Schedule plan change
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - change_option
              properties:
                plan_id:
                  type: string
                external_plan_id:
                  type: string
                change_option:
                  type: string
                  enum:
                    - requested_date
                    - end_of_subscription_term
                    - immediate
                change_date:
                  type: string
                  format: date-time
      responses:
        '200':
          description: The subscription with the scheduled change.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
  /ingest:
    post:
      operationId: ingestEvents
      tags:
        - Events
      summary: Ingest events
      description: >-
        Ingests a batch of usage events into Orb's metering pipeline. Each event
        is idempotent via its idempotency_key and must reference exactly one of
        customer_id or external_customer_id. Pass debug=true to receive a
        per-event accept/duplicate breakdown in the response.
      parameters:
        - name: debug
          in: query
          description: When true, returns a debug breakdown of processed and ignored events.
          schema:
            type: boolean
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IngestRequest'
      responses:
        '200':
          description: The ingestion result, including any events that failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IngestResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /events/{event_id}/amend:
    parameters:
      - name: event_id
        in: path
        required: true
        schema:
          type: string
    put:
      operationId: amendEvent
      tags:
        - Events
      summary: Amend event
      description: Replaces the properties of a previously ingested event.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EventAmend'
      responses:
        '200':
          description: The amended event reference.
          content:
            application/json:
              schema:
                type: object
                properties:
                  amended:
                    type: string
                    description: The idempotency key of the amended event.
  /events/search:
    post:
      operationId: searchEvents
      tags:
        - Events
      summary: Search events
      description: Searches raw ingested events by event_ids or timeframe.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                event_ids:
                  type: array
                  items:
                    type: string
                timeframe_start:
                  type: string
                  format: date-time
                timeframe_end:
                  type: string
                  format: date-time
      responses:
        '200':
          description: Matching events.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Event'
  /events/volume:
    get:
      operationId: getEventVolume
      tags:
        - Events
      summary: Get event volume
      description: Returns counts of ingested events bucketed over a timeframe.
      parameters:
        - name: timeframe_start
          in: query
          required: true
          schema:
            type: string
            format: date-time
        - name: timeframe_end
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Event volume buckets.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        timeframe_start:
                          type: string
                          format: date-time
                        timeframe_end:
                          type: string
                          format: date-time
                        count:
                          type: integer
  /metrics:
    get:
      operationId: listMetrics
      tags:
        - Metrics
      summary: List metrics
      parameters:
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of billable metrics.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetricList'
    post:
      operationId: createMetric
      tags:
        - Metrics
      summary: Create metric
      description: Creates a billable metric defined by a SQL expression over events.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MetricCreate'
      responses:
        '201':
          description: The newly created metric.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Metric'
  /metrics/{metric_id}:
    parameters:
      - name: metric_id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: getMetric
      tags:
        - Metrics
      summary: Get metric
      responses:
        '200':
          description: The requested metric.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Metric'
  /invoices:
    get:
      operationId: listInvoices
      tags:
        - Invoices
      summary: List invoices
      parameters:
        - name: customer_id
          in: query
          schema:
            type: string
        - name: subscription_id
          in: query
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: string
            enum:
              - draft
              - issued
              - paid
              - synced
              - void
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of invoices.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoiceList'
    post:
      operationId: createInvoice
      tags:
        - Invoices
      summary: Create a one-off invoice
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceCreate'
      responses:
        '201':
          description: The newly created one-off invoice.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
  /invoices/{invoice_id}:
    parameters:
      - name: invoice_id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: fetchInvoice
      tags:
        - Invoices
      summary: Fetch invoice
      responses:
        '200':
          description: The requested invoice.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
        '404':
          $ref: '#/components/responses/NotFound'
  /invoices/{invoice_id}/issue:
    parameters:
      - name: invoice_id
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: issueInvoice
      tags:
        - Invoices
      summary: Issue invoice
      description: Transitions a draft invoice to issued, triggering payment collection.
      responses:
        '200':
          description: The issued invoice.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
  /invoices/{invoice_id}/void:
    parameters:
      - name: invoice_id
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: voidInvoice
      tags:
        - Invoices
      summary: Void invoice
      responses:
        '200':
          description: The voided invoice.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invoice'
  /customers/{customer_id}/credits:
    parameters:
      - $ref: '#/components/parameters/CustomerId'
    get:
      operationId: fetchCustomerCredits
      tags:
        - Credits
      summary: Fetch customer credit balance
      description: Returns the unexpired, available credit blocks for a customer.
      responses:
        '200':
          description: The customer's credit blocks.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreditBlockList'
  /customers/{customer_id}/credits/ledger:
    parameters:
      - $ref: '#/components/parameters/CustomerId'
    get:
      operationId: fetchCustomerCreditsLedger
      tags:
        - Credits
      summary: Fetch customer credits ledger
      description: Returns the full ledger of credit additions, decrements, and expirations.
      parameters:
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated credit ledger.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LedgerEntryList'
  /customers/{customer_id}/credits/ledger_entries:
    parameters:
      - $ref: '#/components/parameters/CustomerId'
    post:
      operationId: createLedgerEntry
      tags:
        - Credits
      summary: Create ledger entry
      description: Adds, sets expiry, voids, or amends credits on a customer's ledger.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LedgerEntryCreate'
      responses:
        '201':
          description: The created ledger entry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LedgerEntry'
  /customers/{customer_id}/credits/top_ups:
    parameters:
      - $ref: '#/components/parameters/CustomerId'
    post:
      operationId: createTopUp
      tags:
        - Credits
      summary: Create top-up
      description: Configures an automatic credit top-up that fires when a balance falls below a threshold.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TopUpCreate'
      responses:
        '201':
          description: The created top-up.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TopUp'
    get:
      operationId: listTopUps
      tags:
        - Credits
      summary: List top-ups
      responses:
        '200':
          description: The customer's top-ups.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/TopUp'
  /prices:
    get:
      operationId: listPrices
      tags:
        - Prices
      summary: List prices
      parameters:
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of prices.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PriceList'
    post:
      operationId: createPrice
      tags:
        - Prices
      summary: Create price
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PriceCreate'
      responses:
        '201':
          description: The newly created price.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Price'
  /prices/{price_id}:
    parameters:
      - name: price_id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: fetchPrice
      tags:
        - Prices
      summary: Fetch price
      responses:
        '200':
          description: The requested price.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Price'
  /prices/evaluate:
    post:
      operationId: evaluatePrices
      tags:
        - Prices
      summary: Evaluate multiple prices
      description: Evaluates one or more prices against a set of events over a timeframe.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - timeframe_start
              properties:
                timeframe_start:
                  type: string
                  format: date-time
                timeframe_end:
                  type: string
                  format: date-time
                price_evaluations:
                  type: array
                  items:
                    type: object
                    properties:
                      price_id:
                        type: string
                      external_price_id:
                        type: string
                      filter:
                        type: string
      responses:
        '200':
          description: The evaluated price results.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        price_id:
                          type: string
                        amount:
                          type: string
  /items:
    get:
      operationId: listItems
      tags:
        - Items
      summary: List items
      parameters:
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of items.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ItemList'
    post:
      operationId: createItem
      tags:
        - Items
      summary: Create item
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
      responses:
        '201':
          description: The newly created item.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Item'
  /items/{item_id}:
    parameters:
      - name: item_id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: fetchItem
      tags:
        - Items
      summary: Fetch item
      responses:
        '200':
          description: The requested item.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Item'
  /coupons:
    get:
      operationId: listCoupons
      tags:
        - Coupons
      summary: List coupons
      parameters:
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of coupons.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CouponList'
    post:
      operationId: createCoupon
      tags:
        - Coupons
      summary: Create coupon
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CouponCreate'
      responses:
        '201':
          description: The newly created coupon.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Coupon'
  /coupons/{coupon_id}/archive:
    parameters:
      - name: coupon_id
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: archiveCoupon
      tags:
        - Coupons
      summary: Archive coupon
      responses:
        '200':
          description: The archived coupon.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Coupon'
  /alerts:
    get:
      operationId: listAlerts
      tags:
        - Alerts
      summary: List alerts
      parameters:
        - name: customer_id
          in: query
          schema:
            type: string
        - name: subscription_id
          in: query
          schema:
            type: string
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: A paginated list of alerts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AlertList'
    post:
      operationId: createAlert
      tags:
        - Alerts
      summary: Create alert
      description: Creates a usage, cost, or credit-balance alert on a customer or subscription.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AlertCreate'
      responses:
        '201':
          description: The newly created alert.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Alert'
  /alerts/{alert_id}:
    parameters:
      - name: alert_id
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: fetchAlert
      tags:
        - Alerts
      summary: Fetch alert
      responses:
        '200':
          description: The requested alert.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Alert'
  /alerts/{alert_id}/enable:
    parameters:
      - name: alert_id
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: enableAlert
      tags:
        - Alerts
      summary: Enable alert
      responses:
        '200':
          description: The enabled alert.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Alert'
  /alerts/{alert_id}/disable:
    parameters:
      - name: alert_id
        in: path
        required: true
        schema:
          type: string
    post:
      operationId: disableAlert
      tags:
        - Alerts
      summary: Disable alert
      responses:
        '200':
          description: The disabled alert.
          content:
            application/json:
              s

# --- truncated at 32 KB (56 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/orb-billing/refs/heads/main/openapi/orb-billing-openapi.yml