{"openapi":"3.1.0","info":{"title":"seatledger team ledger","version":"0.1.1","description":"What a team's coding-agent seats and tokens buy, per developer, model and client, from each developer's pushed daily aggregates. Authenticate with `Authorization: Bearer slk_…` (a developer's key from `seatledger team join`, or the owner key from POST /teams). Errors are JSON with code, cause, fix, retryable. A push carries counts and ids only; every string field has a no-whitespace pattern."},"servers":[{"url":"https://agentwares-agentcheck.vercel.app"}],"components":{"securitySchemes":{"key":{"type":"http","scheme":"bearer","bearerFormat":"slk_…"}},"schemas":{"Error":{"type":"object","required":["code","cause","fix","retryable"],"properties":{"code":{"type":"string"},"cause":{"type":"string"},"fix":{"type":"string"},"retryable":{"type":"boolean"}}},"Push":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"schema":{"type":"string","const":"seatledger.push/v1"},"days":{"minItems":1,"maxItems":400,"type":"array","items":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},"rows":{"maxItems":20000,"type":"array","items":{"type":"object","properties":{"day":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"client":{"type":"string","enum":["claude-code","codex"]},"client_version":{"type":"string","maxLength":40,"pattern":"^([0-9A-Za-z][0-9A-Za-z.+_-]{0,39})?$"},"model":{"type":"string","maxLength":80,"pattern":"^(\\*|[A-Za-z0-9][A-Za-z0-9._:@/+-]{0,79})$"},"project":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9._-]{1,64}$"},"requests":{"type":"integer","minimum":0,"maximum":10000000},"input_tokens":{"type":"integer","minimum":0,"maximum":1000000000000000},"output_tokens":{"type":"integer","minimum":0,"maximum":1000000000000000},"cache_read_tokens":{"type":"integer","minimum":0,"maximum":1000000000000000},"cache_write_tokens":{"type":"integer","minimum":0,"maximum":1000000000000000},"api_equivalent_usd":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000000},{"type":"null"}]}},"required":["day","client","client_version","model","requests","input_tokens","output_tokens","cache_read_tokens","cache_write_tokens","api_equivalent_usd"],"additionalProperties":false}},"findings":{"default":[],"maxItems":200,"type":"array","items":{"type":"object","properties":{"client":{"type":"string","enum":["claude-code","codex"]},"model":{"type":"string","maxLength":80,"pattern":"^(\\*|[A-Za-z0-9][A-Za-z0-9._:@/+-]{0,79})$"},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"version":{"type":"string","maxLength":40,"pattern":"^([0-9A-Za-z][0-9A-Za-z.+_-]{0,39})?$"},"previous_version":{"type":"string","maxLength":40,"pattern":"^([0-9A-Za-z][0-9A-Za-z.+_-]{0,39})?$"},"version_changed":{"type":"boolean"},"changes":{"minItems":1,"maxItems":6,"type":"array","items":{"type":"object","properties":{"metric":{"type":"string","enum":["tokens_per_request","cache_read_share","cache_write_per_read","tokens_per_turn","cache_1h_write_share","tokens_per_quota_percent"]},"before":{"type":"number","minimum":-1000000000000,"maximum":1000000000000},"after":{"type":"number","minimum":-1000000000000,"maximum":1000000000000},"change":{"type":"number","minimum":-1000000000000,"maximum":1000000000000}},"required":["metric","before","after","change"],"additionalProperties":false}},"cache_reads_per_request":{"type":"array","prefixItems":[{"type":"number","minimum":-1000000000000,"maximum":1000000000000},{"type":"number","minimum":-1000000000000,"maximum":1000000000000}],"items":false,"minItems":2,"maxItems":2},"cache_writes_per_request":{"type":"array","prefixItems":[{"type":"number","minimum":-1000000000000,"maximum":1000000000000},{"type":"number","minimum":-1000000000000,"maximum":1000000000000}],"items":false,"minItems":2,"maxItems":2}},"required":["client","model","date","version","previous_version","version_changed","changes","cache_reads_per_request","cache_writes_per_request"],"additionalProperties":false}}},"required":["schema","days","rows"],"additionalProperties":false},"CreateTeam":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"accept_terms":{"type":"boolean"},"name":{"type":"string","pattern":"^[\\p{L}\\p{N}][\\p{L}\\p{N} ._&'-]{0,59}$"},"member":{"type":"string","pattern":"^[a-z0-9][a-z0-9._-]{0,31}$"},"owner_email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["accept_terms"],"additionalProperties":false},"Join":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"invite":{"type":"string","minLength":8,"maxLength":300},"member":{"type":"string","pattern":"^[a-z0-9][a-z0-9._-]{0,31}$"}},"required":["invite","member"],"additionalProperties":false},"Checkout":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tier":{"type":"string","enum":["team","business"]}},"required":["tier"],"additionalProperties":false}}},"paths":{"/api/seatledger/v1/teams":{"post":{"summary":"Create a free team with no human; returns an owner key (once) and an invite link","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTeam"}}}},"responses":{"201":{"description":"team_id, owner_key, invite_url, plan, next"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"too many teams from this client this hour (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/join":{"post":{"summary":"Join a team with its invite; returns this developer's own key (once)","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Join"}}}},"responses":{"201":{"description":"key, team, member, plan"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not a live invite (INVITE_NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"that name already has a key on the team (MEMBER_EXISTS)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/push":{"post":{"summary":"Push one developer's daily aggregates; the rows for each day in `days` become exactly the pushed rows","security":[{"key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Push"}}}},"responses":{"200":{"description":"days_replaced, rows_stored, rows_removed, days_skipped (older than the plan keeps), findings {received, new, seen_before}, alerts"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body over 4 MB (PAYLOAD_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/team":{"get":{"summary":"The team, its plan and its seats","security":[{"key":[]}],"responses":{"200":{"description":"plan, seats_used, members"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/summary":{"get":{"summary":"Totals and tables by day, month, developer, model and client, and the rate-change findings","security":[{"key":[]}],"parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string","pattern":"^(\\d{4}-\\d{2}-\\d{2}|\\d{1,4}[dDwWmM])$"},"description":"a date or a span back from today (30d, 12w, 13m); never earlier than the plan keeps"}],"responses":{"200":{"description":"the team summary"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/export.csv":{"get":{"summary":"Every stored row in range as CSV (owner; Team and Business)","security":[{"key":[]}],"parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string","pattern":"^(\\d{4}-\\d{2}-\\d{2}|\\d{1,4}[dDwWmM])$"},"description":"a date or a span back from today (30d, 12w, 13m); never earlier than the plan keeps"}],"responses":{"200":{"description":"text/csv","content":{"text/csv":{}}},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/invites":{"post":{"summary":"A new invite link (owner); the previous one stops working","security":[{"key":[]}],"responses":{"201":{"description":"invite_url"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/members/{id}":{"delete":{"summary":"Revoke a developer's key (owner), freeing its seat; their history stays","security":[{"key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"revoked"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"no live key with that id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/checkout":{"post":{"summary":"A Stripe Checkout link for Team or Business (owner); a person with a card pays","security":[{"key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Checkout"}}}},"responses":{"200":{"description":"checkout_url"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/seatledger/v1/portal":{"post":{"summary":"A Stripe customer-portal link: invoices, card, cancel (owner)","security":[{"key":[]}],"responses":{"200":{"description":"portal_url"},"400":{"description":"invalid input (INVALID_INPUT, INVALID_JSON, TERMS_NOT_ACCEPTED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"missing or unknown key (UNAUTHORIZED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"past the plan's developer cap (SEAT_LIMIT) or a paid feature (PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"a developer key where the owner's is needed (OWNER_ONLY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}