{"openapi":"3.1.0","info":{"title":"CrbonFree API","version":"1.0.0","description":"Track AI workload carbon emissions: ingest provider telemetry, calculate per-tier CO₂ with versioned factors, generate signed retirement receipts.","contact":{"name":"CrbonFree","url":"https://crbonfree.com"}},"servers":[{"url":"https://api.crbonfree.com","description":"Production"},{"url":"http://localhost:3001","description":"Local dev"}],"tags":[{"name":"Projects","description":"Workspace organization for telemetry"},{"name":"Usage","description":"Token/cost/carbon aggregates"},{"name":"Telemetry","description":"Event-level telemetry + emissions detail"},{"name":"Billing","description":"Receipts, audit packs, overage, periods, plan tier"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Clerk-issued session JWT, sent as `Authorization: Bearer <token>`. Obtain it via `clerk.session.getToken()` in the browser SDK."},"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Long-lived API key issued via POST /api/v1/api-keys. Format: ck_live_<32 chars base64url>. Sent in the X-API-Key header (NOT in Authorization — that header is reserved for the Clerk JWT path)."}},"schemas":{"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string","example":"INSUFFICIENT_PERMISSIONS"},"message":{"type":"string","example":"Insufficient permissions for this organization"},"upgradeUrl":{"type":"string","example":"/billing"},"details":{"type":"object","additionalProperties":{}}},"required":["success","error","message"]},"ProjectPublic":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Default"},"isDefault":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","isDefault","createdAt","updatedAt"]},"ProjectWithUsage":{"allOf":[{"$ref":"#/components/schemas/ProjectPublic"},{"type":"object","properties":{"connectionCount":{"type":"integer","minimum":0},"last30dCo2Kg":{"type":"number","minimum":0}},"required":["connectionCount","last30dCo2Kg"]}]},"UsageSummary":{"type":"object","properties":{"range":{"type":"object","properties":{"start":{"type":"string"},"end":{"type":"string"}},"required":["start","end"]},"totals":{"type":"object","properties":{"totalTokens":{"type":"number"},"promptTokens":{"type":"number"},"completionTokens":{"type":"number"},"totalCostUsd":{"type":"number"},"requestCount":{"type":"number"},"carbonKg":{"type":"number"},"electricityKwh":{"type":"number"},"offsetCostUsd":{"type":"number"}},"required":["totalTokens","promptTokens","completionTokens","totalCostUsd","requestCount","carbonKg","electricityKwh","offsetCostUsd"]},"chart":{"type":"object","properties":{"labels":{"type":"array","items":{"type":"string"}},"datasets":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"data":{"type":"array","items":{"type":"number"}}},"required":["label","data"]}}},"required":["labels","datasets"]}},"required":["range","totals","chart"]},"UsageBreakdownItem":{"type":"object","properties":{"model":{"type":"string"},"promptTokens":{"type":"number"},"completionTokens":{"type":"number"},"totalTokens":{"type":"number"},"requestCount":{"type":"number"},"costUsd":{"type":"number"},"percentage":{"type":"number"},"carbonKg":{"type":"number"},"offsetCostUsd":{"type":"number"},"electricityKwh":{"type":"number"}},"required":["model","promptTokens","completionTokens","totalTokens","requestCount","costUsd","percentage","carbonKg","offsetCostUsd","electricityKwh"]},"DailyUsageRow":{"type":"object","properties":{"date":{"type":"string"},"projectName":{"type":"string"},"promptTokens":{"type":"number"},"completionTokens":{"type":"number"},"totalTokens":{"type":"number"},"requestCount":{"type":"number"},"costUsd":{"type":"number"},"carbonKg":{"type":"number"},"energyKwh":{"type":"number"}},"required":["date","promptTokens","completionTokens","totalTokens","requestCount","costUsd","carbonKg","energyKwh"]},"DailyUsageExportRow":{"type":"object","properties":{"date":{"type":"string"},"project_name":{"type":"string"},"prompt_tokens":{"type":"number"},"completion_tokens":{"type":"number"},"total_tokens":{"type":"number"},"request_count":{"type":"number"},"cost_usd":{"type":"number"},"carbon_kg":{"type":"number"},"energy_kwh":{"type":"number"}},"required":["date","project_name","prompt_tokens","completion_tokens","total_tokens","request_count","cost_usd","carbon_kg","energy_kwh"]},"PaginationMeta":{"type":"object","properties":{"page":{"type":"integer","minimum":0},"limit":{"type":"integer","exclusiveMinimum":0},"total":{"type":"integer","minimum":0},"totalPages":{"type":"integer","minimum":0}},"required":["page","limit","total","totalPages"]},"TelemetrySummary":{"type":"object","properties":{"total_co2_kg":{"type":"number"},"total_co2_lower_bound_kg":{"type":"number"},"total_co2_upper_bound_kg":{"type":"number"},"total_tokens":{"type":"number"},"cached_vs_uncached":{"type":"object","properties":{"uncached_tokens":{"type":"number"},"cached_tokens":{"type":"number"},"cache_creation_tokens":{"type":"number"},"cached_co2_savings_kg":{"type":"number"}},"required":["uncached_tokens","cached_tokens","cache_creation_tokens","cached_co2_savings_kg"]},"per_model":{"type":"array","items":{"type":"object","properties":{"model":{"type":"string"},"total_tokens":{"type":"number"},"co2_kg":{"type":"number"},"percentage":{"type":"number"}},"required":["model","total_tokens","co2_kg","percentage"]}},"daily_chart":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"co2_kg":{"type":"number"},"tokens":{"type":"number"}},"required":["date","co2_kg","tokens"]}},"factors_version":{"type":"string"},"period":{"type":"object","properties":{"start":{"type":"string"},"end":{"type":"string"}},"required":["start","end"]}},"required":["total_co2_kg","total_co2_lower_bound_kg","total_co2_upper_bound_kg","total_tokens","cached_vs_uncached","per_model","daily_chart","factors_version","period"]},"TelemetryModel":{"type":"object","properties":{"provider":{"type":"string"},"model":{"type":"string"},"total_tokens":{"type":"number"},"total_co2_kg":{"type":"number"},"event_count":{"type":"integer"},"first_seen":{"type":"string"},"last_seen":{"type":"string"}},"required":["provider","model","total_tokens","total_co2_kg","event_count","first_seen","last_seen"]},"RetirementStatus":{"type":"object","properties":{"periodId":{"type":"string","format":"uuid"},"periodStart":{"type":"string","format":"date-time"},"periodEnd":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["collecting","calculating","awaiting_payment","retiring","retired","pending_signature","action_required"]},"carbonKg":{"type":"number"},"electricityKwh":{"type":"number"},"amountChargedCents":{"type":["integer","null"]},"paidAt":{"type":["string","null"],"format":"date-time"},"closedAt":{"type":["string","null"],"format":"date-time"},"receipt":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"co2Kg":{"type":"number"},"isSigned":{"type":"boolean"},"verificationUrl":{"type":"string"},"pdfUrl":{"type":["string","null"]},"signedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","co2Kg","isSigned","verificationUrl","pdfUrl","signedAt"]}},"required":["periodId","periodStart","periodEnd","status","carbonKg","electricityKwh","amountChargedCents","paidAt","closedAt","receipt"]},"CarbonReceipt":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"billingPeriodId":{"type":"string","format":"uuid"},"co2Kg":{"type":"number"},"serialAllocations":{"type":"array","items":{"type":"object","properties":{"serialNumber":{"type":"string"},"totalKgCo2e":{"type":"number"}},"required":["serialNumber","totalKgCo2e"]}},"verificationUrl":{"type":"string"},"previewUrl":{"type":["string","null"]},"pdfUrl":{"type":["string","null"]},"isSigned":{"type":"boolean"},"signedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","billingPeriodId","co2Kg","serialAllocations","verificationUrl","previewUrl","pdfUrl","isSigned","signedAt","createdAt"]},"AuditPack":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"packYear":{"type":"integer"},"packMonth":{"type":"integer","minimum":1,"maximum":12},"periodStart":{"type":"string","format":"date-time"},"periodEnd":{"type":"string","format":"date-time"},"blobUrl":{"type":"string"},"manifestHash":{"type":"string"},"receiptCount":{"type":"integer","minimum":0},"fileCount":{"type":"integer","minimum":0},"totalBytes":{"type":"integer","minimum":0},"generatedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","organizationId","packYear","packMonth","periodStart","periodEnd","blobUrl","manifestHash","receiptCount","fileCount","totalBytes","generatedAt","createdAt"]}}},"paths":{"/api/v1/projects":{"get":{"operationId":"projects.list","tags":["Projects"],"summary":"List projects","description":"Lists projects in the active organization. With `?include=usage`, returns per-project connection count + last-30d CO₂ rollup.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["usage"]},"required":false,"name":"include","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Projects list","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"projects":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ProjectPublic"}},{"type":"array","items":{"$ref":"#/components/schemas/ProjectWithUsage"}}]}},"required":["projects"]}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/usage/summary":{"get":{"operationId":"usage.getSummary","tags":["Usage"],"summary":"Get usage summary","description":"Returns totals (tokens/cost/carbon/energy/offset) plus a daily chart for the requested date range, optionally scoped to a project.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["7d","30d","90d","365d"],"default":"30d"},"required":false,"name":"range","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"startDate","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"endDate","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"projectId","in":"query"}],"responses":{"200":{"description":"Usage summary","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/UsageSummary"}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/usage/breakdown":{"get":{"operationId":"usage.getBreakdown","tags":["Usage"],"summary":"Get per-model breakdown","description":"Returns per-model token/cost/carbon/energy rollups (with `percentage` share of total tokens) for the requested date range, optionally scoped to a project.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["7d","30d","90d","365d"],"default":"30d"},"required":false,"name":"range","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"startDate","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"endDate","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"projectId","in":"query"}],"responses":{"200":{"description":"Per-model breakdown","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/UsageBreakdownItem"}}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/usage/daily":{"get":{"operationId":"usage.getDaily","tags":["Usage"],"summary":"Get daily aggregates","description":"Returns flat daily token/cost/carbon rows for the requested date range, optionally scoped to a project.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["7d","30d","90d","365d"],"default":"30d"},"required":false,"name":"range","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"startDate","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"endDate","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"projectId","in":"query"}],"responses":{"200":{"description":"Daily aggregates","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/DailyUsageRow"}}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/usage/export":{"get":{"operationId":"usage.exportDaily","tags":["Usage"],"summary":"Export daily aggregates as CSV or JSON","description":"Returns a downloadable file (CSV uses RFC-4180 quoting; JSON is a flat array — no envelope). The `format` query selects the content type. When `projectId` is set, every row carries that project's name in the `project_name` column.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","enum":["7d","30d","90d","365d"],"default":"30d"},"required":false,"name":"range","in":"query"},{"schema":{"type":"string","enum":["csv","json"],"default":"csv"},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"projectId","in":"query"}],"responses":{"200":{"description":"Exported file (CSV or JSON depending on `format` param)","content":{"text/csv":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DailyUsageExportRow"}}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/telemetry/summary":{"get":{"operationId":"telemetry.getSummary","tags":["Telemetry"],"summary":"Get telemetry summary","description":"Returns CO2 totals (with upper/lower bounds), cached-vs-uncached token split, per-model rollups, and a daily chart for the requested date range, optionally scoped to a project.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"start_date","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"required":false,"name":"end_date","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"project_id","in":"query"}],"responses":{"200":{"description":"Telemetry summary","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/TelemetrySummary"}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/telemetry/models":{"get":{"operationId":"telemetry.listModels","tags":["Telemetry"],"summary":"List distinct telemetry models","description":"Returns the set of distinct provider/model pairs seen in the org with total tokens, total CO2, event count, and first/last-seen timestamps.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Distinct models","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"models":{"type":"array","items":{"$ref":"#/components/schemas/TelemetryModel"}}},"required":["models"]}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/billing/retirement-status":{"get":{"operationId":"billing.getRetirementStatus","tags":["Billing"],"summary":"Get carbon retirement status","description":"Customer-facing snapshot of the current billing period's carbon-retirement lifecycle: a translated status (collecting → calculating → awaiting_payment → retiring → retired / pending_signature / action_required), the period's carbon + electricity totals, the amount charged, and a receipt summary (null until credits are retired). Scoped to the authenticated organization. 404 when the org has no periods yet.","security":[{"bearerAuth":[]},{"apiKey":[]}],"responses":{"200":{"description":"Current retirement status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"retirementStatus":{"$ref":"#/components/schemas/RetirementStatus"}},"required":["retirementStatus"]}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/billing/receipts":{"get":{"operationId":"billing.listReceipts","tags":["Billing"],"summary":"List carbon receipts","description":"Paginated list of carbon retirement receipts issued by badge_system. Paywalled: free-tier orgs receive 402 PAYMENT_REQUIRED with an `upgradeUrl`.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Paginated carbon receipts","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/CarbonReceipt"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["success","data","pagination"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment required — feature gated behind paid tier; clients should redirect to upgradeUrl","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/billing/receipts/{id}":{"get":{"operationId":"billing.getReceipt","tags":["Billing"],"summary":"Get a carbon receipt","description":"Returns a single receipt by id, scoped to the caller's organization. Paywalled.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"00000000-0000-0000-0000-000000000001"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Carbon receipt","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"receipt":{"$ref":"#/components/schemas/CarbonReceipt"}},"required":["receipt"]}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment required — feature gated behind paid tier; clients should redirect to upgradeUrl","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/billing/audit-packs":{"get":{"operationId":"billing.listAuditPacks","tags":["Billing"],"summary":"List audit packs","description":"Paginated list of generated audit packs (one per month, ZIP exports of receipts + manifest). Paywalled.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Paginated audit packs","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditPack"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["success","data","pagination"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment required — feature gated behind paid tier; clients should redirect to upgradeUrl","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/billing/audit-packs/{id}":{"get":{"operationId":"billing.getAuditPack","tags":["Billing"],"summary":"Get an audit pack","description":"Returns a single audit pack by id, scoped to the caller's organization. Paywalled.","security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"00000000-0000-0000-0000-000000000001"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Audit pack","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"auditPack":{"$ref":"#/components/schemas/AuditPack"}},"required":["auditPack"]}},"required":["success","data"]}}}},"400":{"description":"Bad request — validation failed or malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — token missing, expired, or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment required — feature gated behind paid tier; clients should redirect to upgradeUrl","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests — rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until next request allowed"},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"webhooks":{}}