{"openapi":"3.1.0","info":{"title":"UltraEdge Admin API","version":"0.1.0","description":"UltraEdge platform operators only: settings for every marketplace rule, audit log, company verification decisions, listing review, plus Monitoring (health, counts, series, sweeps), Ops (queue, disputes, suspensions, announcements) and Finance (fee ledger, summary, statements, invoices)."},"servers":[{"url":"https://api.ultraedge.ai","description":"production"}],"tags":[{"name":"System"},{"name":"Auth"},{"name":"Signals"},{"name":"Admin"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"country":{"type":"string"},"city":{"type":["string","null"]},"region":{"type":["string","null"]},"website":{"type":["string","null"]},"phone":{"type":["string","null"]},"is_house":{"type":"boolean"},"verification_status":{"type":"string"},"status":{"type":"string"},"rating_avg":{"type":["number","null"]},"rating_count":{"type":"number"},"completed_deals":{"type":"number"},"created_at":{"type":"string"}},"required":["id","name","country","city","region","website","phone","is_house","verification_status","status","rating_avg","rating_count","completed_deals","created_at"]},"Problem":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"number"},"detail":{"type":"string"},"code":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status"]},"LoginRequest":{"type":"object","properties":{"email":{"type":"string","maxLength":200,"format":"email"},"password":{"type":"string","maxLength":200}},"required":["email","password"]},"Signal":{"type":"object","properties":{"id":{"type":"string"},"scope":{"type":"string"},"severity":{"type":"string","enum":["good","info","urgent","error"]},"kind":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"entity_type":{"type":["string","null"]},"entity_id":{"type":["string","null"]},"data":{"type":["object","null"],"additionalProperties":{}},"expires_at":{"type":["string","null"]},"created_at":{"type":"string"}},"required":["id","scope","severity","kind","title","body","entity_type","entity_id","data","expires_at","created_at"]}},"parameters":{}},"paths":{"/v1/health":{"get":{"x-audience":["public","buyer","vendor","company-admin","admin","service"],"tags":["System"],"summary":"Liveness and database check","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"db":{"type":"string"},"version":{"type":"string"},"environment":{"type":"string"},"time":{"type":"string"}},"required":["status","db","version","environment","time"]}}}}}}},"/v1/auth/login":{"post":{"x-audience":["public","buyer","vendor","company-admin","admin","service"],"tags":["Auth"],"summary":"Log in with email and password","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"number"}},"required":["access_token","refresh_token","token_type","expires_in"]}}}},"401":{"description":"Bad credentials","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/auth/refresh":{"post":{"x-audience":["public","buyer","vendor","company-admin","admin","service"],"tags":["Auth"],"summary":"Exchange a refresh token for new tokens. Tokens rotate on every use; replaying a used token revokes the whole login family.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"refresh_token":{"type":"string","maxLength":2000}},"required":["refresh_token"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"number"}},"required":["access_token","refresh_token","token_type","expires_in"]}}}},"401":{"description":"Invalid","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/auth/logout":{"post":{"x-audience":["buyer","vendor","company-admin","admin","service"],"tags":["Auth"],"summary":"Revoke the refresh token's login family, or with all_devices every session (access tokens stop working immediately).","security":[{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"refresh_token":{"type":"string","maxLength":2000},"all_devices":{"type":"boolean"}}}}}},"responses":{"204":{"description":"Logged out"},"401":{"description":"Unauthorized","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/me":{"get":{"x-audience":["buyer","vendor","company-admin","admin","service"],"tags":["Auth"],"summary":"Current user and company","security":[{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user":{},"company":{"$ref":"#/components/schemas/Company"}},"required":["company"]}}}},"401":{"description":"Unauthorized","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/companies/{id}/verification":{"put":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: approve or reject company verification","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["verified","rejected","pending"]},"note":{"type":"string","maxLength":500}},"required":["status"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Company"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/listings/{id}/approve":{"post":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: approve a listing in review","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Wrong status","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/listings/{id}/reject":{"post":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: reject a listing in review (back to draft)","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Wrong status","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/settings":{"get":{"x-audience":["admin"],"tags":["Admin"],"summary":"All platform settings: current values, schema with defaults, descriptions and an `enforced` flag per key, and an ETag for safe updates","security":[{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"values":{"type":"object","additionalProperties":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"schema":{"type":"object","additionalProperties":{"type":"object","properties":{},"additionalProperties":{}}},"version":{"type":"number"}},"required":["values","schema","version"]}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"x-audience":["admin"],"tags":["Admin"],"summary":"Update one or more settings. If-Match with the ETag from GET is required (428 without it, 412 if stale). All keys are validated first; either every change applies or none does. Audited.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string","maxLength":500},{"type":"array","items":{"type":"string","maxLength":20},"maxItems":50}]}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"values":{"type":"object","additionalProperties":{"anyOf":[{"type":"number"},{"type":"boolean"},{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"schema":{"type":"object","additionalProperties":{"type":"object","properties":{},"additionalProperties":{}}},"version":{"type":"number"}},"required":["values","schema","version"]}}}},"400":{"description":"Invalid key or value","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"ETag mismatch","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"428":{"description":"If-Match required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/audit":{"get":{"x-audience":["admin"],"tags":["Admin"],"summary":"Audit log, newest first","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","maxLength":40},"required":false,"name":"entity_type","in":"query"},{"schema":{"type":"string","maxLength":80},"required":false,"name":"entity_id","in":"query"},{"schema":{"type":"string","maxLength":60},"required":false,"name":"action","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{},"additionalProperties":{}}},"next_cursor":{"type":["string","null"]}},"required":["items","next_cursor"]}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/signals":{"get":{"x-audience":["buyer","vendor","company-admin","admin"],"tags":["Signals"],"summary":"My company's signal feed, newest first, with the unread count. Severity is good | info | urgent | error and decides the colour everywhere. First page comes from the in-memory hot list; use cursor for history (30 days).","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","enum":["good","info","urgent","error"],"description":"Only this severity (history pages only)"},"required":false,"description":"Only this severity (history pages only)","name":"severity","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Signal"}},"next_cursor":{"type":["string","null"]},"unread":{"type":"integer"},"stream":{"type":"string","description":"How to open the live stream"}},"required":["items","next_cursor","unread","stream"]}}}},"400":{"description":"Invalid cursor","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/signals/seen":{"post":{"x-audience":["buyer","vendor","company-admin","admin"],"tags":["Signals"],"summary":"Mark signals seen up to a cursor (default: everything). The unread badge counts only newer items.","security":[{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"cursor":{"type":"string","description":"Mark seen up to this item cursor (created_at|id). Omit to mark everything seen."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"unread":{"type":"integer"}},"required":["unread"]}}}}}}},"/v1/signals/stream-token":{"post":{"x-audience":["buyer","vendor","company-admin","admin"],"tags":["Signals"],"summary":"A 60-second ticket for the WebSocket stream. Open wss://<api>/v1/signals/stream?t=<token>. The socket sends {type:'hello', items} then {type:'signals', items:[...]} as they happen; send 'ping' for 'pong'.","security":[{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"expires_in":{"type":"integer"},"url":{"type":"string"}},"required":["token","expires_in","url"]}}}}}}},"/v1/market/signals":{"get":{"x-audience":["public","buyer","vendor","company-admin","admin","service"],"tags":["Signals"],"summary":"Anonymised public market feed: new listings, price drops, closed prices, scarcity, newly verified companies. No token needed. Cached for 5 seconds at the edge; stream at wss://<api>/v1/market/stream.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Signal"}},"next_cursor":{"type":["string","null"]}},"required":["items","next_cursor"]}}}},"400":{"description":"Invalid cursor","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/signals/hubs/{scope}":{"get":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: hot-list size and open sockets for a scope ('market' or a company id)","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","maxLength":80},"required":true,"name":"scope","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}}}}},"/v1/assets/{slot}":{"get":{"x-audience":["public","buyer","vendor","company-admin","admin","service"],"tags":["System"],"summary":"A generated brand asset by slot (e.g. role-buyer). ?n=1 for the second variant.","parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9-]{2,60}$"},"required":true,"name":"slot","in":"path"},{"schema":{"type":["integer","null"],"minimum":0,"maximum":7,"default":0},"required":false,"name":"n","in":"query"}],"responses":{"200":{"description":"Image"},"304":{"description":"Not modified"},"404":{"description":"No image for that slot","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/assets/generate":{"post":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: ask Leonardo.ai for images for a slot. Results arrive via the webhook.","security":[{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"slot":{"type":"string","pattern":"^[a-z0-9-]{2,60}$"},"prompt":{"type":"string","minLength":10,"maxLength":2000},"width":{"type":"integer","minimum":256,"maximum":1536,"default":1024},"height":{"type":"integer","minimum":256,"maximum":1536,"default":1024},"quantity":{"type":"integer","minimum":1,"maximum":4,"default":2}},"required":["slot","prompt"]}}}},"responses":{"202":{"description":"Requested","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"502":{"description":"Leonardo error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Not configured","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/assets/generate-brand-set":{"post":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: request the whole brand set (role icons, hero, empty states, badge).","security":[{"bearer":[]}],"responses":{"202":{"description":"Requested","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"503":{"description":"Not configured","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/assets/adopt":{"post":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: fetch a finished Leonardo generation by id and store it under a slot (recovery when a callback was missed).","security":[{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"generation_id":{"type":"string","minLength":8,"maxLength":80},"slot":{"type":"string","pattern":"^[a-z0-9-]{2,60}$"}},"required":["generation_id","slot"]}}}},"responses":{"200":{"description":"Stored","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"502":{"description":"Leonardo error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Not configured","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/assets":{"get":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: stored asset slots and pending generations","security":[{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}}}}},"/v1/admin/sandboxes":{"post":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: create (or return) the sandbox for a person. Three verified companies with one user each, seeded with the demo listings, bids and counters.","security":[{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"owner":{"type":"string","minLength":3,"maxLength":200},"label":{"type":"string","maxLength":120}},"required":["owner"]}}}},"responses":{"200":{"description":"Existing sandbox","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"201":{"description":"Created and seeded","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"403":{"description":"Admin only","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/sandboxes/{id}":{"get":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: sandbox details and counts.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9]{6,40}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/sandboxes/{id}/reset":{"post":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: wipe everything the sandbox's companies did (listings, bids, deals, signals, watchlist), revoke their tokens, and re-seed.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9]{6,40}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Reset","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/admin/sandboxes/{id}/tokens":{"post":{"x-audience":["admin"],"tags":["Admin"],"summary":"Admin: issue an access and refresh pair for one of the sandbox's users (buyer, seller or trader), optionally read-only for a shared view. Used by the demo site so passwords never exist outside the database.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9]{6,40}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["buyer","seller","trader"]},"readonly":{"type":"boolean","default":false,"description":"Issue a viewer token: every write is refused with 403 read_only. Used for shared sandbox links."}},"required":["role"]}}}},"responses":{"200":{"description":"Tokens","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/monitoring/overview":{"get":{"x-audience":["admin","service"],"tags":["Monitoring"],"summary":"Current marketplace counts: companies, listings, bids (24 h), deals, signals (24 h), sandboxes, last sweep.","security":[{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"403":{"description":"Admin or service only","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/monitoring/metrics":{"get":{"x-audience":["admin","service"],"tags":["Monitoring"],"summary":"Bucketed counts for a window: bids placed, deals opened and completed, listings published, signals written. Zero-filled, contiguous.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","enum":["24h","7d"],"default":"24h"},"required":false,"name":"window","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"400":{"description":"Bad window","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/monitoring/sweeps":{"get":{"x-audience":["admin","service"],"tags":["Monitoring"],"summary":"Recent scheduled sweep runs, newest first, with result counts and errors.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}}}}},"/v1/monitoring/health":{"get":{"x-audience":["admin","service"],"tags":["Monitoring"],"summary":"Deep health: exercises D1, KV, the market signal hub and R2 with per-check latency. ok only if every required check passes.","security":[{"bearer":[]}],"responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"503":{"description":"Degraded","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}}}}},"/v1/ops/queue":{"get":{"x-audience":["admin"],"tags":["Ops"],"summary":"Everything waiting for a human: companies pending verification, listings in review, disputed deals, unpaid deals past their hold, companies suspended in the last 7 days. Oldest first, with the call that resolves each.","security":[{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"403":{"description":"Admin only","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/ops/deals/{id}/resolve":{"post":{"x-audience":["admin"],"tags":["Ops"],"summary":"Resolve a disputed deal: continue returns it to the state before the dispute; cancel cancels it and releases stock. Note required; both parties are signalled.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"outcome":{"type":"string","enum":["continue","cancel"]},"note":{"type":"string","minLength":3,"maxLength":500}},"required":["outcome","note"]}}}},"responses":{"200":{"description":"Deal","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Not disputed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/ops/companies/{id}/suspend":{"post":{"x-audience":["admin"],"tags":["Ops"],"summary":"Suspend a company (reason required). Its users cannot act until reinstated.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","minLength":3,"maxLength":500}},"required":["reason"]}}}},"responses":{"200":{"description":"Company","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Already suspended","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/ops/companies/{id}/reinstate":{"post":{"x-audience":["admin"],"tags":["Ops"],"summary":"Reinstate a suspended company.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Company","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Already active","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/ops/strikes":{"get":{"x-audience":["admin"],"tags":["Ops"],"summary":"Strikes (expired unpaid holds), newest first, optionally for one company.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":false,"name":"company_id","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}}}}},"/v1/ops/announcements":{"post":{"x-audience":["admin"],"tags":["Ops"],"summary":"Post a market announcement to one sandbox's market feed and stream (default: the shared data). Deduplicated by key.","security":[{"bearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":2,"maxLength":80},"body":{"type":"string","minLength":2,"maxLength":500},"severity":{"type":"string","enum":["info","urgent"],"default":"info"},"sandbox_id":{"type":"string","pattern":"^[a-z0-9]{1,40}$"},"key":{"type":"string","maxLength":80}},"required":["title","body"]}}}},"responses":{"200":{"description":"Duplicate key, nothing written","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"201":{"description":"Written","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}}}}},"/v1/finance/summary":{"get":{"x-audience":["admin"],"tags":["Finance"],"summary":"Admin: GMV, fees by status, outstanding and overdue, escrow in flight, and a per-day series for a window (default 30d, max 365d).","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\d{1,3}d$","default":"30d"},"required":false,"name":"window","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"400":{"description":"Bad window","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/finance/ledger":{"get":{"x-audience":["admin"],"tags":["Finance"],"summary":"Admin: fee ledger entries, newest first, filter by status, company or deal.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","enum":["accrued","invoiced","paid","waived"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"company_id","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"deal_id","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{},"additionalProperties":{}}},"next_cursor":{"type":["string","null"]}},"required":["items","next_cursor"]}}}}}}},"/v1/finance/ledger/{id}":{"post":{"x-audience":["admin"],"tags":["Finance"],"summary":"Admin: move a ledger entry: accrued → invoiced → paid, or accrued|invoiced → waived (note required). The payer is signalled.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["invoiced","paid","waived"]},"note":{"type":"string","maxLength":500}},"required":["status"]}}}},"responses":{"200":{"description":"Entry","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"400":{"description":"Note required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Illegal move","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/finance/statement":{"get":{"x-audience":["buyer","vendor","company-admin","admin"],"tags":["Finance"],"summary":"My company's statement for a window: GMV bought and sold, fees accrued, paid, outstanding and overdue, with the entries. Admins pass company_id.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\d{1,3}d$","default":"30d"},"required":false,"name":"window","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"company_id","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"403":{"description":"Not your company","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/finance/deals/{id}/invoice":{"get":{"x-audience":["buyer","vendor","company-admin","admin"],"tags":["Finance"],"summary":"Invoice document for a deal: issuer, bill-to, goods lines, fee line, escrow state, due date and status. Parties and admins only.","security":[{"bearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Invoice","content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":{}}}}},"404":{"description":"Not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"webhooks":{}}