{"components":{"responses":{"Problem":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"description":"RFC 9457 problem detail."}},"schemas":{"Account":{"properties":{"billing_status":{"enum":["active","past_due","suspended"],"type":"string"},"cycle_limit_units":{"minimum":1,"type":"integer"},"cycle_usage_units":{"minimum":0,"type":"integer"},"email":{"format":"email","type":"string"},"id":{"type":"string"},"services":{"items":{"type":"string"},"type":"array"}},"required":["id","email","billing_status","services","cycle_usage_units","cycle_limit_units"],"type":"object"},"DemoToken":{"properties":{"access_token":{"type":"string"},"expires_in":{"const":300,"type":"integer"},"rate_limit_per_minute":{"const":3,"type":"integer"},"scope":{"const":"api:read","type":"string"},"token_type":{"const":"Bearer","type":"string"}},"required":["access_token","token_type","expires_in","scope","rate_limit_per_minute"],"type":"object"},"Health":{"properties":{"status":{"enum":["ok"],"type":"string"}},"required":["status"],"type":"object"},"Jwk":{"properties":{"alg":{"const":"EdDSA","type":"string"},"crv":{"const":"Ed25519","type":"string"},"kid":{"type":"string"},"kty":{"const":"OKP","type":"string"},"use":{"const":"sig","type":"string"},"x":{"type":"string"}},"required":["kty","crv","use","alg","kid","x"],"type":"object"},"Problem":{"properties":{"code":{"type":"string"},"detail":{"type":"string"},"errors":{"items":{"properties":{"field":{"type":"string"},"reason":{"type":"string"}},"required":["field","reason"],"type":"object"},"type":"array"},"instance":{"type":"string"},"request_id":{"type":"string"},"status":{"type":"integer"},"title":{"type":"string"},"type":{"format":"uri","type":"string"}},"required":["type","title","status","detail","instance","code","request_id"],"type":"object"},"Signup":{"properties":{"account_id":{"format":"uuid","type":"string"},"api_key":{"readOnly":true,"type":"string"},"email":{"format":"email","type":"string"},"services":{"items":{"type":"string"},"type":"array"}},"required":["account_id","email","api_key","services"],"type":"object"},"Token":{"properties":{"access_token":{"type":"string"},"expires_in":{"const":600,"type":"integer"},"scope":{"type":"string"},"token_type":{"const":"Bearer","type":"string"}},"required":["access_token","token_type","expires_in","scope"],"type":"object"},"UsageEvent":{"additionalProperties":false,"properties":{"account_id":{"type":"string"},"id":{"format":"uuid","type":"string"},"occurred_at":{"format":"date-time","type":"string"},"operation":{"pattern":"^[a-z][a-z0-9_.-]{0,79}$","type":"string"},"service":{"pattern":"^[a-z][a-z0-9-]{0,39}$","type":"string"},"source":{"enum":["edge","service"],"type":"string"},"units":{"const":1,"type":"integer"}},"required":["id","account_id","service","operation","units","occurred_at","source"],"type":"object"}},"securitySchemes":{"bearerAuth":{"bearerFormat":"JWT","scheme":"bearer","type":"http"},"clientCredentials":{"scheme":"basic","type":"http"}}},"info":{"description":"Accounts, access-token issuance, and metering intake for tiny services.","title":"tiny centre API","version":"1.0.0"},"openapi":"3.1.0","paths":{"/.well-known/jwks.json":{"get":{"operationId":"jwks","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"keys":{"items":{"$ref":"#/components/schemas/Jwk"},"type":"array"}},"required":["keys"],"type":"object"}}},"description":"Active and retiring Ed25519 verification keys.","headers":{"Cache-Control":{"schema":{"type":"string"}}}}},"security":[]}},"/health/live":{"get":{"operationId":"live","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}},"description":"Process is alive."}},"security":[]}},"/health/ready":{"get":{"operationId":"ready","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}},"description":"Required datastore is ready."},"503":{"$ref":"#/components/responses/Problem"}},"security":[]}},"/openapi.json":{"get":{"operationId":"openapi","responses":{"200":{"content":{"application/json":{}},"description":"This OpenAPI 3.1 document, represented as JSON."}},"security":[]}},"/v1/account":{"get":{"operationId":"account","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}},"description":"Authenticated account and current local usage."},"401":{"$ref":"#/components/responses/Problem"},"403":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":["api:read"]}]}},"/v1/accounts":{"post":{"operationId":"createAccount","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"email":{"format":"email","type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signup"}}},"description":"Account created. The API key is not returned again.","headers":{"Cache-Control":{"schema":{"const":"no-store","type":"string"}}}},"400":{"$ref":"#/components/responses/Problem"},"409":{"$ref":"#/components/responses/Problem"},"429":{"$ref":"#/components/responses/Problem"}},"security":[],"summary":"Create a developer account and issue its API key once."}},"/v1/demo-tokens":{"post":{"operationId":"issueDemoToken","responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoToken"}}},"description":"Five-minute weather token limited to three calls per minute.","headers":{"Cache-Control":{"schema":{"const":"no-store","type":"string"}}}},"429":{"$ref":"#/components/responses/Problem"}},"security":[],"summary":"Mint a narrow, short-lived weather demo token."}},"/v1/tokens":{"post":{"operationId":"issueToken","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"additionalProperties":false,"properties":{"audience":{"format":"uri","type":"string"},"grant_type":{"const":"client_credentials","type":"string"},"scope":{"type":"string"}},"required":["grant_type","audience"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}},"description":"Signed access token."},"400":{"$ref":"#/components/responses/Problem"},"401":{"$ref":"#/components/responses/Problem"},"403":{"$ref":"#/components/responses/Problem"}},"security":[{"clientCredentials":[]}],"summary":"Exchange an API client ID and secret for a short-lived access token."}},"/v1/usage-events":{"post":{"description":"Idempotently records edge or service completion receipts. Requires a service-principal token with `meter:write` and centre audience.","operationId":"ingestUsage","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"events":{"items":{"$ref":"#/components/schemas/UsageEvent"},"maxItems":1000,"minItems":1,"type":"array"}},"required":["events"],"type":"object"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"properties":{"accepted":{"minimum":0,"type":"integer"},"duplicates":{"minimum":0,"type":"integer"}},"required":["accepted","duplicates"],"type":"object"}}},"description":"Batch accepted; duplicates are reported, not re-counted."},"400":{"$ref":"#/components/responses/Problem"},"401":{"$ref":"#/components/responses/Problem"},"403":{"$ref":"#/components/responses/Problem"},"422":{"$ref":"#/components/responses/Problem"}},"security":[{"bearerAuth":["meter:write"]}]}}},"servers":[{"url":"https://tiny.kjuulh.io"}]}