{
  "openapi": "3.1.0",
  "info": {
    "title": "Lucius Billing API",
    "version": "1.0",
    "description": "The Lucius Billing API lets you submit usage events, query contracts, and retrieve invoices for your C2C (Contract-to-Cash) billing programs.\n\n## Base URL\n\n```\nhttps://api.lucius.finance\n```\n\nAll endpoints are prefixed with `/v1/billing`.\n\n## Authentication\n\nTwo machine-readable schemes are supported.\n\n### API keys (Billing API)\n\nAuthenticate every Billing API request with an API key via the `Authorization` header:\n\n```\nAuthorization: Bearer luc_live_abc123...\n```\n\nYou can also use the `X-Api-Key` header. Create and manage keys from the Lucius dashboard under **Settings > API Keys**. Keys are self-serve — no sales form required.\n\n### OAuth 2.1 scopes (MCP and agents)\n\nThe MCP server at `https://api.lucius.finance/mcp` uses OAuth 2.1 (PKCE). Request only the scopes you need:\n\n| Scope | Access |\n|-------|--------|\n| `read:analytics` | Burn, runway, revenue trends, forecasts |\n| `read:reports` | P&L, balance sheet, cash flow, deferred revenue |\n| `read:transactions` | Bank balances and transactions |\n| `read:invoices` | Receivables, payables, customers, vendors, contracts |\n| `read:ledger` | Journal entries, chart of accounts, account activity |\n| `read:gmail` | Gmail threads for invoice intake |\n| `write:invoices` | Create/update invoices, counterparties, contracts, POs |\n| `write:transactions` | Reconcile and classify bank transactions |\n| `write:ledger` | Ledger corrections, splits, VAT, schedules |\n| `write:tax` | Submit tax returns (irreversible) |\n\nProtected-resource metadata: `https://api.lucius.finance/.well-known/oauth-protected-resource`\n\n## Pagination\n\nList endpoints use cursor-based pagination. Pass `limit` (1–100, default 50) and `starting_after` (the `id` or `number` of the last item) to page through results. The response includes `has_more` to indicate additional pages.\n\n## Idempotency\n\nUsage events use `event_id` as an idempotency key. Submitting the same `event_id` twice returns a success without creating a duplicate.\n",
    "contact": {
      "name": "Lucius Engineering",
      "url": "https://lucius.finance",
      "email": "support@lucius.finance"
    }
  },
  "servers": [
    {
      "url": "https://api.lucius.finance",
      "description": "Production"
    },
    {
      "url": "https://api-dev.lucius.finance",
      "description": "Development"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    },
    {
      "ApiKeyAuth": []
    },
    {
      "OAuth2": [
        "read:invoices",
        "write:invoices"
      ]
    }
  ],
  "tags": [
    {
      "name": "Usage",
      "description": "Submit and query usage events for metered billing."
    },
    {
      "name": "Contracts",
      "description": "List contracts and inspect pricing programs."
    },
    {
      "name": "Invoices",
      "description": "List and inspect generated invoices with line items."
    }
  ],
  "paths": {
    "/v1/billing/usage": {
      "post": {
        "operationId": "submitUsage",
        "summary": "Submit usage events",
        "description": "Submit up to 100 usage events in a single request. Each event is validated against the contract's pricing program, persisted, rated immediately, and the corresponding invoice is updated.\n\nEvents are idempotent — submitting the same `event_id` twice returns success without creating a duplicate.\n",
        "tags": [
          "Usage"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitUsageRequest"
              },
              "example": {
                "events": [
                  {
                    "external_contract_id": "acme-corp-2026",
                    "event_id": "evt-2026-03-001",
                    "metric": "revenue_amount_invoiced",
                    "quantity": 10000,
                    "timestamp": "2026-03-25T12:00:00.000Z"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Submission result with per-event status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitUsageResponse"
                },
                "example": {
                  "accepted": 1,
                  "rejected": 0,
                  "events": [
                    {
                      "event_id": "evt-2026-03-001",
                      "status": "accepted"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "get": {
        "operationId": "listUsageEvents",
        "summary": "List usage events",
        "description": "Returns a paginated list of usage events, newest first. Filter by contract, metric, date range, or rating status.",
        "tags": [
          "Usage"
        ],
        "parameters": [
          {
            "name": "contract",
            "in": "query",
            "description": "Filter by contract external ID.",
            "schema": {
              "type": "string"
            },
            "example": "acme-corp-2026"
          },
          {
            "name": "metric",
            "in": "query",
            "description": "Filter by metric name.",
            "schema": {
              "type": "string"
            },
            "example": "revenue_amount_invoiced"
          },
          {
            "name": "from",
            "in": "query",
            "description": "Start of service period (YYYY-MM-DD).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "End of service period (YYYY-MM-DD).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by event status.",
            "schema": {
              "type": "string",
              "enum": [
                "accepted",
                "rated"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of usage events.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageEventList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "usage_event",
                      "id": "evt-2026-03-001",
                      "contract": "acme-corp-2026",
                      "metric": "revenue_amount_invoiced",
                      "quantity": 10000,
                      "service_period_start": "2026-03-25",
                      "service_period_end": "2026-03-25",
                      "ingested_at": "2026-03-05T11:21:59.868Z",
                      "status": "rated"
                    }
                  ],
                  "has_more": false,
                  "total_count": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/billing/usage/{event_id}": {
      "get": {
        "operationId": "getUsageEvent",
        "summary": "Get a usage event",
        "description": "Retrieve a single usage event by its idempotency key (`event_id`).",
        "tags": [
          "Usage"
        ],
        "parameters": [
          {
            "name": "event_id",
            "in": "path",
            "required": true,
            "description": "The idempotency key of the event.",
            "schema": {
              "type": "string"
            },
            "example": "evt-2026-03-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The usage event.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageEvent"
                },
                "example": {
                  "object": "usage_event",
                  "id": "evt-2026-03-001",
                  "contract": "acme-corp-2026",
                  "metric": "revenue_amount_invoiced",
                  "quantity": 10000,
                  "service_period_start": "2026-03-25",
                  "service_period_end": "2026-03-25",
                  "ingested_at": "2026-03-05T11:21:59.868Z",
                  "status": "rated"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/billing/contracts": {
      "get": {
        "operationId": "listContracts",
        "summary": "List contracts",
        "description": "Returns all C2C contracts for the authenticated company, newest first. Optionally filter by status.",
        "tags": [
          "Contracts"
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Filter by contract status.",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "active",
                "completed",
                "cancelled",
                "terminated"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of contracts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "contract",
                      "id": "acme-corp-2026",
                      "customer_name": "Acme Corp",
                      "status": "active",
                      "start_date": "2026-01-01",
                      "end_date": "2027-01-01",
                      "currency": "USD",
                      "billing_cadence": "monthly",
                      "metrics": [
                        "revenue_amount_invoiced"
                      ]
                    }
                  ],
                  "has_more": false,
                  "total_count": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/billing/contracts/{ext_id}": {
      "get": {
        "operationId": "getContract",
        "summary": "Get a contract",
        "description": "Retrieve a single contract by its external ID.",
        "tags": [
          "Contracts"
        ],
        "parameters": [
          {
            "name": "ext_id",
            "in": "path",
            "required": true,
            "description": "The external ID of the contract.",
            "schema": {
              "type": "string"
            },
            "example": "acme-corp-2026"
          }
        ],
        "responses": {
          "200": {
            "description": "The contract.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contract"
                },
                "example": {
                  "object": "contract",
                  "id": "acme-corp-2026",
                  "customer_name": "Acme Corp",
                  "status": "active",
                  "start_date": "2026-01-01",
                  "end_date": "2027-01-01",
                  "currency": "USD",
                  "metrics": [
                    "revenue_amount_invoiced"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/billing/contracts/{ext_id}/pricing": {
      "get": {
        "operationId": "getContractPricing",
        "summary": "Get active pricing program",
        "description": "Returns the currently active (approved) pricing program for a contract, including all pricing rules.",
        "tags": [
          "Contracts"
        ],
        "parameters": [
          {
            "name": "ext_id",
            "in": "path",
            "required": true,
            "description": "The external ID of the contract.",
            "schema": {
              "type": "string"
            },
            "example": "acme-corp-2026"
          }
        ],
        "responses": {
          "200": {
            "description": "The active pricing program.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricingProgram"
                },
                "example": {
                  "object": "pricing_program",
                  "contract": "acme-corp-2026",
                  "version": 1,
                  "effective_date": "2026-01-01",
                  "rules": [
                    {
                      "id": "a1b2c3d4",
                      "name": "Platform Subscription",
                      "type": "subscription",
                      "model": "flat",
                      "amount": "2000",
                      "currency": "USD",
                      "frequency": "monthly"
                    },
                    {
                      "id": "e5f6a7b8",
                      "name": "Usage Fee",
                      "type": "usage",
                      "model": "percentage",
                      "rate": 0.05,
                      "metric": "revenue_amount_invoiced"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/billing/contracts/{ext_id}/pricing-rules": {
      "post": {
        "operationId": "addPricingRule",
        "summary": "Add a pricing rule",
        "description": "Appends a new pricing rule to the contract's active program, creating a new approved pricing program version (append-only; prior versions are preserved). Use this to set up counterparty-scoped rules — e.g. waiving the maker fee for a specific counterparty — before submitting usage.\n",
        "tags": [
          "Contracts"
        ],
        "parameters": [
          {
            "name": "ext_id",
            "in": "path",
            "required": true,
            "description": "The external ID of the contract.",
            "schema": {
              "type": "string"
            },
            "example": "acme-corp-2026"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PricingRule"
              },
              "example": {
                "name": "Maker fee waiver — counterparty acme-markets",
                "type": "usage",
                "model": "percentage",
                "rate": 0,
                "metric": "trading_volume",
                "counterparty": "acme-markets",
                "counterparty_side": "maker"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created rule and new program version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricingRuleResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "A rule with the supplied id already exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/contracts/{ext_id}/pricing-rules/{rule_id}": {
      "put": {
        "operationId": "updatePricingRule",
        "summary": "Update a pricing rule",
        "description": "Merges the supplied fields into an existing rule and creates a new approved pricing program version.\n",
        "tags": [
          "Contracts"
        ],
        "parameters": [
          {
            "name": "ext_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "rule_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PricingRule"
              },
              "example": {
                "rate": 0.00005
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated rule and new program version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricingRuleResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "operationId": "deletePricingRule",
        "summary": "Delete a pricing rule",
        "description": "Removes a rule and creates a new approved pricing program version.",
        "tags": [
          "Contracts"
        ],
        "parameters": [
          {
            "name": "ext_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "rule_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Confirmation with the new program version.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "pricing_rule"
                    },
                    "contract": {
                      "type": "string"
                    },
                    "version": {
                      "type": "integer"
                    },
                    "deleted": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/billing/invoices": {
      "get": {
        "operationId": "listInvoices",
        "summary": "List invoices",
        "description": "Returns a paginated list of invoices, newest first. Filter by contract, status, or billing period date range.",
        "tags": [
          "Invoices"
        ],
        "parameters": [
          {
            "name": "contract",
            "in": "query",
            "description": "Filter by contract external ID.",
            "schema": {
              "type": "string"
            },
            "example": "acme-corp-2026"
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by invoice status.",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "sent",
                "viewed",
                "partial",
                "paid",
                "overdue",
                "cancelled"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Billing period start on or after (YYYY-MM-DD).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Billing period end on or before (YYYY-MM-DD).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "starting_after",
            "in": "query",
            "description": "Invoice number to paginate after.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of invoices.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "object": "invoice",
                      "number": "INV-2026-003",
                      "contract": "acme-corp-2026",
                      "status": "draft",
                      "subtotal": 2500,
                      "tax": 0,
                      "total": 2500,
                      "currency": "USD",
                      "billing_period": {
                        "start": "2026-03-01",
                        "end": "2026-03-31"
                      },
                      "issued_date": "2026-03-01",
                      "due_date": "2026-03-15",
                      "paid_date": null,
                      "metrics": [
                        "revenue_amount_invoiced"
                      ]
                    }
                  ],
                  "has_more": false,
                  "total_count": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/billing/invoices/project": {
      "post": {
        "operationId": "projectInvoice",
        "summary": "Create or update a draft invoice",
        "description": "Creates (or updates) a draft invoice for a contract and billing period.\nGenerates subscription / minimum charges for the period and attaches any\nunbilled usage. Use this before or after submitting usage — especially for\nminimum-only contracts that have no usage events.\n",
        "tags": [
          "Invoices"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "external_contract_id",
                  "billing_period_start",
                  "billing_period_end"
                ],
                "properties": {
                  "external_contract_id": {
                    "type": "string",
                    "example": "uibt-csa"
                  },
                  "billing_period_start": {
                    "type": "string",
                    "format": "date",
                    "example": "2026-08-01"
                  },
                  "billing_period_end": {
                    "type": "string",
                    "format": "date",
                    "example": "2026-08-31"
                  }
                }
              },
              "example": {
                "external_contract_id": "uibt-csa",
                "billing_period_start": "2026-08-01",
                "billing_period_end": "2026-08-31"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Draft invoice created or updated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "example": "invoice"
                    },
                    "number": {
                      "type": "string",
                      "example": "C2C-2026-0001"
                    },
                    "contract": {
                      "type": "string",
                      "example": "uibt-csa"
                    },
                    "status": {
                      "type": "string",
                      "example": "draft"
                    },
                    "is_new": {
                      "type": "boolean"
                    },
                    "total": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "billing_period": {
                      "type": "object",
                      "properties": {
                        "start": {
                          "type": "string"
                        },
                        "end": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No billable charges or invalid period."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Contract not found."
          }
        }
      }
    },
    "/v1/billing/invoices/{number}": {
      "get": {
        "operationId": "getInvoice",
        "summary": "Get invoice detail",
        "description": "Retrieve a single invoice with its line items. Line items are computed from rated charges and include subscription fees, one-time fees, and usage charges.",
        "tags": [
          "Invoices"
        ],
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "description": "The invoice number (e.g. `INV-2026-003`).",
            "schema": {
              "type": "string"
            },
            "example": "INV-2026-003"
          }
        ],
        "responses": {
          "200": {
            "description": "The invoice with line items.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDetail"
                },
                "example": {
                  "object": "invoice",
                  "number": "INV-2026-003",
                  "contract": "acme-corp-2026",
                  "status": "draft",
                  "subtotal": 2500,
                  "tax": 0,
                  "total": 2500,
                  "currency": "USD",
                  "billing_period": {
                    "start": "2026-03-01",
                    "end": "2026-03-31"
                  },
                  "issued_date": "2026-03-01",
                  "due_date": "2026-03-15",
                  "paid_date": null,
                  "metrics": [
                    "revenue_amount_invoiced"
                  ],
                  "line_items": [
                    {
                      "description": "Platform Subscription",
                      "quantity": 1,
                      "unit_price": 2000,
                      "amount": 2000
                    },
                    {
                      "description": "Usage Fee",
                      "quantity": 10000,
                      "unit_price": 0.05,
                      "amount": 500
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key as Bearer token: `Authorization: Bearer luc_live_...`. Create keys in the dashboard under Settings > API Keys."
      },
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "API key via header: `X-Api-Key: luc_live_...`"
      },
      "OAuth2": {
        "type": "oauth2",
        "description": "OAuth 2.1 (PKCE) for the Lucius MCP server and agent access. Request least-privilege scopes.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api.lucius.finance/oauth/authorize",
            "tokenUrl": "https://api.lucius.finance/oauth/token",
            "scopes": {
              "read:analytics": "Read burn, runway, revenue trends, and forecasts",
              "read:reports": "Read P&L, balance sheet, cash flow, and deferred revenue",
              "read:transactions": "Read bank balances and transactions",
              "read:invoices": "Read receivables, payables, customers, vendors, and contracts",
              "read:ledger": "Read journal entries, chart of accounts, and account activity",
              "read:gmail": "Read Gmail threads for invoice intake and lead follow-up",
              "write:invoices": "Create and update invoices, counterparties, contracts, and purchase orders",
              "write:transactions": "Reconcile and classify bank transactions",
              "write:ledger": "Post ledger corrections, splits, VAT, and schedules",
              "write:tax": "Submit tax returns (irreversible)"
            }
          }
        }
      }
    },
    "parameters": {
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Number of items to return (1–100, default: 50).",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 50
        }
      },
      "StartingAfter": {
        "name": "starting_after",
        "in": "query",
        "description": "Event ID to paginate after (cursor-based).",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Authentication failed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "missing": {
                "value": {
                  "error": "Missing API key"
                }
              },
              "invalid": {
                "value": {
                  "error": "Invalid API key"
                }
              },
              "expired": {
                "value": {
                  "error": "API key expired"
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Not found"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "SubmitUsageRequest": {
        "type": "object",
        "required": [
          "events"
        ],
        "properties": {
          "events": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/UsageEventInput"
            }
          }
        }
      },
      "UsageEventInput": {
        "type": "object",
        "required": [
          "external_contract_id",
          "event_id",
          "metric",
          "quantity",
          "timestamp"
        ],
        "properties": {
          "external_contract_id": {
            "type": "string",
            "description": "The external ID of the contract this event belongs to."
          },
          "event_id": {
            "type": "string",
            "description": "A unique idempotency key for this event. Duplicates are silently accepted."
          },
          "metric": {
            "type": "string",
            "description": "The metric name as defined in the contract's pricing program."
          },
          "quantity": {
            "type": "number",
            "minimum": 0,
            "description": "The quantity for this event (e.g. settled USD volume). Must be non-negative."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When the usage occurred (ISO 8601)."
          },
          "window_start": {
            "type": "string",
            "format": "date",
            "description": "Optional service period start (defaults to timestamp date)."
          },
          "window_end": {
            "type": "string",
            "format": "date",
            "description": "Optional service period end (defaults to timestamp date)."
          },
          "counterparty": {
            "type": "string",
            "description": "Optional counterparty for this event. Used to match counterparty-scoped pricing rules (e.g. a fee waiver that only applies when trading with a specific counterparty).\n",
            "example": "acme-markets"
          },
          "side": {
            "type": "string",
            "enum": [
              "maker",
              "taker"
            ],
            "description": "Which side of the trade the customer was on. Used by counterparty-scoped rules."
          },
          "applied_rate": {
            "type": "number",
            "minimum": 0,
            "description": "Optional resolved-upstream rate (decimal, e.g. 0.00005 = 0.5 bps). Overrides the matched pricing rule's model for this event: charge = quantity × applied_rate.\n"
          },
          "fee_amount": {
            "type": "number",
            "minimum": 0,
            "description": "Optional resolved-upstream fee in the contract currency. Authoritative — overrides both the pricing rule and applied_rate. Use for per-trade discounts or waivers (fee_amount: 0) computed before submission.\n"
          }
        }
      },
      "SubmitUsageResponse": {
        "type": "object",
        "required": [
          "accepted",
          "rejected",
          "events"
        ],
        "properties": {
          "accepted": {
            "type": "integer",
            "description": "Number of events accepted."
          },
          "rejected": {
            "type": "integer",
            "description": "Number of events rejected."
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "event_id",
                "status"
              ],
              "properties": {
                "event_id": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "accepted",
                    "rejected"
                  ]
                },
                "error": {
                  "type": "string",
                  "description": "Rejection reason (only present when status is rejected)."
                }
              }
            }
          }
        }
      },
      "UsageEvent": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "usage_event"
          },
          "id": {
            "type": "string",
            "description": "The event's idempotency key."
          },
          "contract": {
            "type": "string",
            "description": "Contract external ID."
          },
          "metric": {
            "type": "string"
          },
          "quantity": {
            "type": "number"
          },
          "service_period_start": {
            "type": "string",
            "format": "date"
          },
          "service_period_end": {
            "type": "string",
            "format": "date"
          },
          "ingested_at": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "enum": [
              "accepted",
              "rated"
            ]
          }
        }
      },
      "UsageEventList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsageEvent"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "total_count": {
            "type": "integer"
          }
        }
      },
      "Contract": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "contract"
          },
          "id": {
            "type": "string",
            "description": "Contract external ID."
          },
          "customer_name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "active",
              "completed",
              "cancelled",
              "terminated"
            ]
          },
          "start_date": {
            "type": "string",
            "format": "date"
          },
          "end_date": {
            "type": "string",
            "format": "date"
          },
          "currency": {
            "type": "string"
          },
          "billing_cadence": {
            "type": "string",
            "enum": [
              "monthly",
              "weekly",
              "annual"
            ]
          },
          "metrics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Usage metric names from the active pricing program."
          }
        }
      },
      "ContractList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Contract"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "total_count": {
            "type": "integer"
          }
        }
      },
      "PricingRule": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "subscription",
              "one_time",
              "usage"
            ]
          },
          "model": {
            "type": "string",
            "enum": [
              "flat",
              "percentage",
              "threshold",
              "tiered"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Flat amount (for flat model)."
          },
          "rate": {
            "type": "number",
            "description": "Rate multiplier (for percentage model)."
          },
          "metric": {
            "type": "string",
            "description": "Metric name (for usage rules)."
          },
          "frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "weekly",
              "annual"
            ],
            "description": "Billing frequency (for subscription rules)."
          },
          "monthly_cap": {
            "type": "string",
            "description": "Monthly cap amount (for percentage model)."
          },
          "currency": {
            "type": "string"
          },
          "counterparty": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ],
            "description": "Restricts a usage rule to events from these counterparties (matched against the event's `counterparty`). Omit for a default rule that applies to all counterparties.\n"
          },
          "counterparty_side": {
            "type": "string",
            "enum": [
              "maker",
              "taker",
              "any"
            ],
            "description": "Restricts a counterparty-scoped rule to events on this side of the trade. An explicit `maker`/`taker` rule takes precedence over a side-agnostic (`any`) rule.\n"
          }
        }
      },
      "PricingRuleResponse": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "pricing_rule"
          },
          "contract": {
            "type": "string",
            "description": "Contract external ID."
          },
          "version": {
            "type": "integer",
            "description": "The new pricing program version number."
          },
          "rule": {
            "$ref": "#/components/schemas/PricingRule"
          }
        }
      },
      "PricingProgram": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "pricing_program"
          },
          "contract": {
            "type": "string",
            "description": "Contract external ID."
          },
          "version": {
            "type": "integer"
          },
          "effective_date": {
            "type": "string",
            "format": "date"
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PricingRule"
            }
          }
        }
      },
      "BillingPeriod": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "format": "date"
          },
          "end": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "invoice"
          },
          "number": {
            "type": "string",
            "description": "Invoice number (e.g. `INV-2026-003`)."
          },
          "contract": {
            "type": "string",
            "description": "Contract external ID."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "sent",
              "viewed",
              "partial",
              "paid",
              "overdue",
              "cancelled"
            ]
          },
          "subtotal": {
            "type": "number"
          },
          "tax": {
            "type": "number"
          },
          "total": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "billing_period": {
            "$ref": "#/components/schemas/BillingPeriod"
          },
          "issued_date": {
            "type": "string",
            "format": "date"
          },
          "due_date": {
            "type": "string",
            "format": "date"
          },
          "paid_date": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "metrics": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "InvoiceList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Invoice"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "total_count": {
            "type": "integer"
          }
        }
      },
      "LineItem": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "quantity": {
            "type": "number"
          },
          "unit_price": {
            "type": "number",
            "nullable": true
          },
          "amount": {
            "type": "number"
          }
        }
      },
      "InvoiceDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Invoice"
          },
          {
            "type": "object",
            "properties": {
              "line_items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LineItem"
                }
              }
            }
          }
        ]
      }
    }
  }
}
