{
  "openapi": "3.1.0",
  "info": {
    "title": "Usage Lab API",
    "version": "1.0.0",
    "summary": "Usage metering for AI and SaaS: idempotent usage events, meters and monthly rollups.",
    "description": "Send usage events with idempotency keys, aggregate them per meter (sum, count, unique_count) and read monthly rollups per customer. Late events are accepted within a 30-day window. Stripe export runs in dry-run mode.",
    "contact": {
      "name": "Canada Site Ops",
      "email": "canada.site.ops@gmail.com",
      "url": "https://usage-lab.pages.dev/"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://usage-lab.pages.dev/terms/"
    }
  },
  "servers": [
    {
      "url": "https://usage-lab.pages.dev"
    }
  ],
  "externalDocs": {
    "url": "https://usage-lab.pages.dev/docs/"
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "paths": {
    "/api/v1/usage": {
      "post": {
        "operationId": "recordUsage",
        "summary": "Record one usage event or a batch (max 100)",
        "description": "A single event, an array of events, or {\"events\": [...]}. Batches are all-or-nothing on validation errors. Retrying with the same idempotency key and payload returns the original event (duplicate); a different payload returns 409 for single events. With a header key, batch events get key:0, key:1, ...",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UsageEvent"
                  },
                  {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "$ref": "#/components/schemas/UsageEvent"
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "events"
                    ],
                    "properties": {
                      "events": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 100,
                        "items": {
                          "$ref": "#/components/schemas/UsageEvent"
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "meter": "llm_tokens",
                "customer": "cus_123",
                "value": 1250
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Single event created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "event": {
                      "$ref": "#/components/schemas/IngestResult"
                    },
                    "duplicate": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "200": {
            "description": "Duplicate single event, or batch result",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "description": "Single event duplicate",
                      "properties": {
                        "event": {
                          "$ref": "#/components/schemas/IngestResult"
                        },
                        "duplicate": {
                          "type": "boolean"
                        }
                      }
                    },
                    {
                      "$ref": "#/components/schemas/BatchResult"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_json": {
                    "value": {
                      "error": {
                        "code": "invalid_json",
                        "message": "..."
                      }
                    }
                  },
                  "empty_batch": {
                    "value": {
                      "error": {
                        "code": "empty_batch",
                        "message": "..."
                      }
                    }
                  },
                  "batch_too_large": {
                    "value": {
                      "error": {
                        "code": "batch_too_large",
                        "message": "..."
                      }
                    }
                  },
                  "invalid_event": {
                    "value": {
                      "error": {
                        "code": "invalid_event",
                        "message": "..."
                      }
                    }
                  },
                  "meter_required": {
                    "value": {
                      "error": {
                        "code": "meter_required",
                        "message": "..."
                      }
                    }
                  },
                  "subscription_required": {
                    "value": {
                      "error": {
                        "code": "subscription_required",
                        "message": "..."
                      }
                    }
                  },
                  "value_required": {
                    "value": {
                      "error": {
                        "code": "value_required",
                        "message": "..."
                      }
                    }
                  },
                  "invalid_value": {
                    "value": {
                      "error": {
                        "code": "invalid_value",
                        "message": "..."
                      }
                    }
                  },
                  "invalid_unique_value": {
                    "value": {
                      "error": {
                        "code": "invalid_unique_value",
                        "message": "..."
                      }
                    }
                  },
                  "unique_value_required": {
                    "value": {
                      "error": {
                        "code": "unique_value_required",
                        "message": "..."
                      }
                    }
                  },
                  "invalid_timestamp": {
                    "value": {
                      "error": {
                        "code": "invalid_timestamp",
                        "message": "..."
                      }
                    }
                  },
                  "idempotency_key_required": {
                    "value": {
                      "error": {
                        "code": "idempotency_key_required",
                        "message": "..."
                      }
                    }
                  },
                  "invalid_idempotency_key": {
                    "value": {
                      "error": {
                        "code": "invalid_idempotency_key",
                        "message": "..."
                      }
                    }
                  },
                  "duplicate_key_in_batch": {
                    "value": {
                      "error": {
                        "code": "duplicate_key_in_batch",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Meter not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "meter_not_found": {
                    "value": {
                      "error": {
                        "code": "meter_not_found",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Idempotency key reused with a different payload; original kept",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConflictError"
                }
              }
            }
          },
          "422": {
            "description": "Timestamp outside the accepted window",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "event_too_old": {
                    "value": {
                      "error": {
                        "code": "event_too_old",
                        "message": "..."
                      }
                    }
                  },
                  "event_in_future": {
                    "value": {
                      "error": {
                        "code": "event_in_future",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/meters": {
      "get": {
        "operationId": "listMeters",
        "summary": "List meters",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "meters": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Meter"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createMeter",
        "summary": "Create a meter",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MeterCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "meter": {
                      "$ref": "#/components/schemas/Meter"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_json": {
                    "value": {
                      "error": {
                        "code": "invalid_json",
                        "message": "..."
                      }
                    }
                  },
                  "invalid_meter_key": {
                    "value": {
                      "error": {
                        "code": "invalid_meter_key",
                        "message": "..."
                      }
                    }
                  },
                  "invalid_aggregation": {
                    "value": {
                      "error": {
                        "code": "invalid_aggregation",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Meter key already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "meter_exists": {
                    "value": {
                      "error": {
                        "code": "meter_exists",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/meters/{meter}/rollups": {
      "get": {
        "operationId": "getRollups",
        "summary": "Monthly rollups per subscription (recomputed from raw events)",
        "parameters": [
          {
            "name": "meter",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Meter key or id."
          },
          {
            "name": "month",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
            },
            "description": "YYYY-MM (UTC). Defaults to the current month."
          },
          {
            "name": "subscription",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter to one subscription/customer."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RollupResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad month",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_month": {
                    "value": {
                      "error": {
                        "code": "invalid_month",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Meter not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "meter_not_found": {
                    "value": {
                      "error": {
                        "code": "meter_not_found",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/meters/{meter}/rollups/export": {
      "post": {
        "operationId": "exportRollups",
        "summary": "Plan/push rollup deltas to Stripe Billing Meters (dry run on this deployment)",
        "parameters": [
          {
            "name": "meter",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Meter key or id."
          },
          {
            "name": "month",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
            },
            "description": "YYYY-MM (UTC). Defaults to the current month."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "meter": {
                      "type": "string"
                    },
                    "month": {
                      "type": "string"
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "off",
                        "dry_run",
                        "live_not_implemented"
                      ]
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Bad month",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_month": {
                    "value": {
                      "error": {
                        "code": "invalid_month",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Meter not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "meter_not_found": {
                    "value": {
                      "error": {
                        "code": "meter_not_found",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "501": {
            "description": "Live export not implemented",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/account": {
      "get": {
        "operationId": "getAccount",
        "summary": "Get your account (plan, limits, first_event_at, event_count)",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAccount",
        "summary": "Permanently delete your account and all its data",
        "description": "Self-serve deletion. Cancels any active Stripe subscription first, then hard-deletes the account, its API keys, meters, usage events and rollups. Irreversible. Later Stripe webhooks for the account are ignored.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "string",
                    "enum": [
                      "delete"
                    ]
                  }
                }
              },
              "example": {
                "confirm": "delete"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "subscription_canceled": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Confirmation missing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "confirmation_required": {
                    "value": {
                      "error": {
                        "code": "confirmation_required",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Subscription could not be cancelled; nothing deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "stripe_error": {
                    "value": {
                      "error": {
                        "code": "stripe_error",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/checkout": {
      "post": {
        "operationId": "createCheckout",
        "summary": "Start a CAD Stripe Checkout for Pro or Ultra",
        "description": "Authenticated by your API key; the account comes from the key. Returns a Stripe Checkout URL (CAD, adaptive pricing off).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "plan"
                ],
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": [
                      "pro",
                      "ultra"
                    ]
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                }
              },
              "example": {
                "plan": "pro"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_plan": {
                    "value": {
                      "error": {
                        "code": "invalid_plan",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/checkout/session": {
      "get": {
        "operationId": "checkoutSessionStatus",
        "summary": "Check a Usage Lab checkout session (status and plan only)",
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^cs_(test|live)_"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "paid",
                        "open",
                        "expired",
                        "invalid",
                        "unavailable",
                        "unknown"
                      ]
                    },
                    "plan": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/stripe": {
      "get": {
        "operationId": "stripePushStatus",
        "tags": [
          "Stripe push"
        ],
        "summary": "Stripe push status: eligibility, key hint, permission check, mappings",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "stripePushConnect",
        "tags": [
          "Stripe push"
        ],
        "summary": "Store your Stripe restricted key (encrypted, never returned) and check its permissions",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "restricted_key"
                ],
                "properties": {
                  "restricted_key": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "restricted_key": "rk_test_..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Invalid key or missing permission",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_key": {
                    "value": {
                      "error": {
                        "code": "invalid_key",
                        "message": "..."
                      }
                    }
                  },
                  "key_rejected": {
                    "value": {
                      "error": {
                        "code": "key_rejected",
                        "message": "..."
                      }
                    }
                  },
                  "key_missing_permission": {
                    "value": {
                      "error": {
                        "code": "key_missing_permission",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on Pro or Ultra, or disabled by admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Key not connected or push off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "no_stripe_key": {
                    "value": {
                      "error": {
                        "code": "no_stripe_key",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "stripePushDisconnect",
        "tags": [
          "Stripe push"
        ],
        "summary": "Disconnect: delete the stored key",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/stripe/settings": {
      "put": {
        "operationId": "stripePushSettings",
        "tags": [
          "Stripe push"
        ],
        "summary": "Turn Stripe push on or off (off by default)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "push_enabled"
                ],
                "properties": {
                  "push_enabled": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "push_enabled": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on Pro or Ultra, or disabled by admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Key not connected or push off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "no_stripe_key": {
                    "value": {
                      "error": {
                        "code": "no_stripe_key",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/stripe/meters/remote": {
      "get": {
        "operationId": "stripeRemoteMeters",
        "tags": [
          "Stripe push"
        ],
        "summary": "List active Billing Meters in your Stripe account",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on Pro or Ultra, or disabled by admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Key not connected or push off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "no_stripe_key": {
                    "value": {
                      "error": {
                        "code": "no_stripe_key",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/stripe/meters": {
      "put": {
        "operationId": "stripeMapMeter",
        "tags": [
          "Stripe push"
        ],
        "summary": "Map a Usage Lab meter to a Stripe meter event_name",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "meter",
                  "event_name"
                ],
                "properties": {
                  "meter": {
                    "type": "string"
                  },
                  "event_name": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "meter": "llm_tokens",
                "event_name": "llm_tokens"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on Pro or Ultra, or disabled by admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Key not connected or push off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "no_stripe_key": {
                    "value": {
                      "error": {
                        "code": "no_stripe_key",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "stripeUnmapMeter",
        "tags": [
          "Stripe push"
        ],
        "summary": "Remove a meter mapping",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "meter"
                ],
                "properties": {
                  "meter": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "meter": "llm_tokens"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on Pro or Ultra, or disabled by admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Key not connected or push off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "no_stripe_key": {
                    "value": {
                      "error": {
                        "code": "no_stripe_key",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/stripe/customers": {
      "put": {
        "operationId": "stripeMapCustomer",
        "tags": [
          "Stripe push"
        ],
        "summary": "Map a subscription id to a Stripe customer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subscription",
                  "stripe_customer_id"
                ],
                "properties": {
                  "subscription": {
                    "type": "string"
                  },
                  "stripe_customer_id": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "subscription": "acme",
                "stripe_customer_id": "cus_..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on Pro or Ultra, or disabled by admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Key not connected or push off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "no_stripe_key": {
                    "value": {
                      "error": {
                        "code": "no_stripe_key",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "stripeUnmapCustomer",
        "tags": [
          "Stripe push"
        ],
        "summary": "Remove a customer mapping",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subscription"
                ],
                "properties": {
                  "subscription": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "subscription": "acme"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on Pro or Ultra, or disabled by admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Key not connected or push off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "no_stripe_key": {
                    "value": {
                      "error": {
                        "code": "no_stripe_key",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/stripe/push": {
      "post": {
        "operationId": "stripePush",
        "tags": [
          "Stripe push"
        ],
        "summary": "Push month-to-date deltas now (dry_run=1 previews and sends nothing)",
        "parameters": [
          {
            "name": "dry_run",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on Pro or Ultra, or disabled by admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "plan_required": {
                    "value": {
                      "error": {
                        "code": "plan_required",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Key not connected or push off",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "no_stripe_key": {
                    "value": {
                      "error": {
                        "code": "no_stripe_key",
                        "message": "..."
                      }
                    }
                  },
                  "push_disabled": {
                    "value": {
                      "error": {
                        "code": "push_disabled",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/integrations/stripe/log": {
      "get": {
        "operationId": "stripePushLog",
        "tags": [
          "Stripe push"
        ],
        "summary": "Recent push log rows",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "..."
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer <api key>"
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "maxLength": 255
        },
        "description": "Required unless every event has idempotency_key. Batches derive <key>:<index>."
      }
    },
    "schemas": {
      "UsageEvent": {
        "type": "object",
        "properties": {
          "meter": {
            "type": "string",
            "description": "Meter key or id. Optional only if the tenant has exactly one meter."
          },
          "subscription": {
            "type": "string",
            "maxLength": 200,
            "description": "Customer/subscription id. Required (or customer)."
          },
          "customer": {
            "type": "string",
            "maxLength": 200,
            "description": "Alias of subscription."
          },
          "value": {
            "type": [
              "number",
              "null"
            ],
            "description": "Required for sum meters; defaults to 1 otherwise."
          },
          "unique_value": {
            "type": [
              "string",
              "number",
              "null"
            ],
            "description": "Required for unique_count meters."
          },
          "timestamp": {
            "oneOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "number",
                "description": "Unix seconds (<1e12) or ms"
              }
            ],
            "description": "Defaults to now. Max 30 days old, max 5 minutes in the future."
          },
          "idempotency_key": {
            "type": "string",
            "maxLength": 255,
            "description": "Per-event key; overrides the header."
          },
          "properties": {
            "description": "Arbitrary JSON stored with the event."
          }
        }
      },
      "IngestResult": {
        "type": "object",
        "required": [
          "status",
          "id",
          "idempotency_key"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "created",
              "duplicate",
              "conflict"
            ]
          },
          "id": {
            "type": "string"
          },
          "idempotency_key": {
            "type": "string"
          },
          "meter": {
            "type": "string"
          },
          "month": {
            "type": "string"
          },
          "error": {
            "type": "string"
          }
        }
      },
      "BatchResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IngestResult"
            }
          },
          "summary": {
            "type": "object",
            "properties": {
              "created": {
                "type": "integer"
              },
              "duplicate": {
                "type": "integer"
              },
              "conflict": {
                "type": "integer"
              }
            }
          }
        }
      },
      "MeterCreate": {
        "type": "object",
        "required": [
          "key",
          "aggregation"
        ],
        "properties": {
          "key": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,63}$"
          },
          "name": {
            "type": "string"
          },
          "aggregation": {
            "$ref": "#/components/schemas/Aggregation"
          },
          "stripe_event_name": {
            "type": "string"
          }
        }
      },
      "Aggregation": {
        "type": "string",
        "enum": [
          "sum",
          "count",
          "unique_count"
        ]
      },
      "Meter": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "key": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "aggregation": {
            "$ref": "#/components/schemas/Aggregation"
          },
          "stripe_event_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RollupResponse": {
        "type": "object",
        "properties": {
          "meter": {
            "$ref": "#/components/schemas/Meter"
          },
          "month": {
            "type": "string"
          },
          "computed_at": {
            "type": "string",
            "format": "date-time"
          },
          "total_quantity": {
            "type": "number"
          },
          "rollups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "subscription": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                },
                "event_count": {
                  "type": "integer"
                },
                "exported_quantity": {
                  "type": "number"
                },
                "pending_export_quantity": {
                  "type": "number"
                },
                "exported_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "additionalProperties": true
          }
        }
      },
      "ConflictError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "const": "idempotency_conflict"
              },
              "message": {
                "type": "string"
              },
              "original_event_id": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}