{"openapi":"3.1.0","info":{"title":"Margint Public API","version":"1.0.0","description":"Read API for per-customer AI margin data. v1 is additive-only: new fields and endpoints may be added, but existing fields will not change type, be renamed, or be removed. Breaking changes ship as /v2/."},"servers":[{"url":"https://app.margint.dev"}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"Workspace API key. Also accepted via `x-api-key` header."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"}},"required":["message","code"]}}},"Range":{"type":"string","enum":["7d","30d","90d"],"default":"30d"},"CustomerRow":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"externalId":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"stripeCustomerId":{"type":"string","nullable":true},"mrrCents":{"type":"integer"},"mrrSource":{"type":"string"},"costCents":{"type":"integer"},"previousCostCents":{"type":"integer"},"marginCents":{"type":"integer"},"marginPercent":{"type":"number"},"previousMarginPercent":{"type":"number"},"marginState":{"type":"string"},"spark":{"type":"array","items":{"type":"integer"}}}},"BudgetCheck":{"oneOf":[{"type":"object","properties":{"allowed":{"const":true},"warnings":{"type":"array"}}},{"type":"object","properties":{"allowed":{"const":false},"reason":{"const":"monthly_limit_exceeded"},"breaches":{"type":"array"}},"required":["allowed","reason","breaches"]}]}}},"security":[{"BearerAuth":[]}],"paths":{"/api/v1/customers":{"get":{"summary":"List customers with margin","description":"Returns one row per tracked customer, including AI cost, MRR, and derived margin over the selected rolling window.","parameters":[{"name":"range","in":"query","schema":{"$ref":"#/components/schemas/Range"}},{"name":"features","in":"query","description":"Optional comma-separated list of feature filters","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CustomerRow"}}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/customers/{externalId}":{"get":{"summary":"Get a single customer by your external ID","parameters":[{"name":"externalId","in":"path","required":true,"schema":{"type":"string"},"description":"The customer's ID as you pass it to the SDK"},{"name":"range","in":"query","schema":{"$ref":"#/components/schemas/Range"}}],"responses":{"200":{"description":"OK"},"404":{"description":"Customer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/costs/overview":{"get":{"summary":"Aggregate cost + revenue + margin over a window","parameters":[{"name":"range","in":"query","schema":{"$ref":"#/components/schemas/Range"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/budgets/check":{"get":{"summary":"Check whether a customer is within active budgets","description":"Returns whether an LLM call for this (customer, feature) would be allowed given the configured budgets. Cached for 60s.","parameters":[{"name":"customer","in":"query","required":true,"schema":{"type":"string"},"description":"Your customer's external ID"},{"name":"feature","in":"query","schema":{"type":"string"},"description":"Optional feature name for feature-scoped budgets"}],"responses":{"200":{"description":"Budget status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetCheck"}}}}}}}}}