{"openapi":"3.1.0","info":{"title":"AEGIS — HITL Reliability Layer","summary":"Human-in-the-loop approval + exactly-once execution for AI agents.","description":"## AEGIS — HITL Reliability Layer\n\nGuarantees human approval and *exactly-once* execution of AI agent actions.\n\n### Authentication\nAll endpoints require `Authorization: Bearer <api_key>`.\n\n### Idempotency\nEvery mutating request must include the headers `Idempotency-Key`, `tenant-id`, and `thread-id`.\n\n### SDK\n`pip install aegis-idempotency` — wraps this API with retry/backoff built-in.\n\nSee [aegis-idempotency on GitHub](https://github.com/cstamigo-droid/aegis-idempotency).","contact":{"name":"AEGIS","url":"https://github.com/cstamigo-droid/aegis-idempotency"},"license":{"name":"Proprietary (core) / MIT (SDK)"},"version":"0.8.0"},"paths":{"/api/v1/hitl/approve":{"post":{"tags":["HITL Public"],"summary":"Approve a pending execution","description":"Approve an execution that is waiting for human review.\n\nDelegates to `lifecycle_manager.approve_execution` and marks the idempotency\nrecord as COMMITTED. Safe to retry with the same `Idempotency-Key`.\n\n**Required headers:** `Authorization`, `Idempotency-Key`, `tenant-id`, `thread-id`.","operationId":"public_approve_api_v1_hitl_approve_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tenant-id","in":"header","required":true,"schema":{"type":"string","description":"UUID of the tenant. Must match the tenant of the Bearer token.","title":"Tenant-Id"},"description":"UUID of the tenant. Must match the tenant of the Bearer token."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","description":"Unique key per operation attempt. Retries must reuse the same key to guarantee exactly-once semantics.","title":"Idempotency-Key"},"description":"Unique key per operation attempt. Retries must reuse the same key to guarantee exactly-once semantics."},{"name":"thread-id","in":"header","required":false,"schema":{"type":"string","description":"UUID of the HITL execution to approve or reject.","title":"Thread-Id"},"description":"UUID of the HITL execution to approve or reject."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveResponse"}}}},"409":{"description":"Duplicate request (already COMMITTED or PENDING) or lifecycle conflict (lock contention, wrong state).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Monthly event quota exceeded for the tenant's plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid Bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Authenticated tenant does not match tenant-id header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Missing required header (Idempotency-Key, tenant-id, or thread-id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/hitl/reject":{"post":{"tags":["HITL Public"],"summary":"Reject a pending execution","description":"Reject an execution that is waiting for human review.\n\nCalls `lifecycle_manager.reject_execution` and marks the idempotency entry as\nCOMMITTED (final state). Safe to retry with the same `Idempotency-Key`.\n\n**Required headers:** `Authorization`, `Idempotency-Key`, `tenant-id`, `thread-id`.","operationId":"public_reject_api_v1_hitl_reject_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tenant-id","in":"header","required":true,"schema":{"type":"string","description":"UUID of the tenant. Must match the tenant of the Bearer token.","title":"Tenant-Id"},"description":"UUID of the tenant. Must match the tenant of the Bearer token."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","description":"Unique key per operation attempt. Retries must reuse the same key to guarantee exactly-once semantics.","title":"Idempotency-Key"},"description":"Unique key per operation attempt. Retries must reuse the same key to guarantee exactly-once semantics."},{"name":"thread-id","in":"header","required":false,"schema":{"type":"string","description":"UUID of the HITL execution to approve or reject.","title":"Thread-Id"},"description":"UUID of the HITL execution to approve or reject."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectResponse"}}}},"409":{"description":"Duplicate request or lifecycle conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Monthly event quota exceeded for the tenant's plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid Bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Authenticated tenant does not match tenant-id header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Missing required header (Idempotency-Key, tenant-id, or thread-id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/hitl/status/{thread_id}":{"get":{"tags":["HITL Public"],"summary":"Get execution status","description":"Return the current HITL status for a given execution thread.\n\nReturns the lifecycle state (WAITING_APPROVAL / APPROVED / REJECTED) and\nthe idempotency state (PENDING / COMMITTED / FAILED) for the given thread,\nscoped to the authenticated tenant.\n\n**Required headers:** `Authorization`, `Idempotency-Key`, `tenant-id`, `thread-id`.","operationId":"public_status_api_v1_hitl_status__thread_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"thread_id","in":"path","required":true,"schema":{"type":"string","title":"Thread Id"}},{"name":"tenant-id","in":"header","required":true,"schema":{"type":"string","description":"UUID of the tenant. Must match the tenant of the Bearer token.","title":"Tenant-Id"},"description":"UUID of the tenant. Must match the tenant of the Bearer token."},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","description":"Unique key per operation attempt. Retries must reuse the same key to guarantee exactly-once semantics.","title":"Idempotency-Key"},"description":"Unique key per operation attempt. Retries must reuse the same key to guarantee exactly-once semantics."},{"name":"thread-id","in":"header","required":false,"schema":{"type":"string","description":"UUID of the HITL execution to approve or reject.","title":"Thread-Id"},"description":"UUID of the HITL execution to approve or reject."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecutionStatusResponse"}}}},"404":{"description":"No execution found for this thread_id under the authenticated tenant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid Bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Authenticated tenant does not match tenant-id header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/usage":{"get":{"tags":["Billing"],"summary":"Get billing usage for the current period","description":"Return billable event count and cost for the authenticated tenant.\n\nDefaults to the current calendar month in UTC. Pass `year` and `month` to\nquery a historical period.","operationId":"get_usage_api_v1_billing_usage_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Billing year (defaults to current year).","title":"Year"},"description":"Billing year (defaults to current year)."},{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":12,"minimum":1},{"type":"null"}],"description":"Billing month 1-12 (defaults to current month).","title":"Month"},"description":"Billing month 1-12 (defaults to current month)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummary"}}}},"401":{"description":"Missing or invalid Bearer token."},"404":{"description":"No billing data found for this period."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/plans":{"get":{"tags":["Billing"],"summary":"List all available pricing plans","description":"Return all available pricing plans with their prices and quotas.\n\nThis endpoint is public — no authentication required.","operationId":"list_plans_api_v1_billing_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlansResponse"}}}}}}},"/api/v1/billing/checkout":{"post":{"tags":["Billing"],"summary":"Create a Stripe Checkout Session to upgrade the current plan","operationId":"create_checkout_api_v1_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"400":{"description":"Invalid plan or already on paid plan."},"503":{"description":"Stripe not configured."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/billing/portal":{"get":{"tags":["Billing"],"summary":"Get a Stripe Customer Portal link to manage subscription","operationId":"customer_portal_api_v1_billing_portal_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}}},"404":{"description":"No Stripe customer found for this tenant."},"503":{"description":"Stripe not configured."}},"security":[{"HTTPBearer":[]}]}},"/api/v1/accounts/signup":{"post":{"tags":["Accounts"],"summary":"Signup","operationId":"signup_api_v1_accounts_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/accounts/keys":{"get":{"tags":["Accounts"],"summary":"List Keys","operationId":"list_keys_api_v1_accounts_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/KeyMetadata"},"type":"array","title":"Response List Keys Api V1 Accounts Keys Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Accounts"],"summary":"Create Key","operationId":"create_key_api_v1_accounts_keys_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/accounts/me":{"get":{"tags":["Accounts"],"summary":"Get Me","operationId":"get_me_api_v1_accounts_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/accounts/keys/{key_prefix}":{"delete":{"tags":["Accounts"],"summary":"Revoke Key","operationId":"revoke_key_api_v1_accounts_keys__key_prefix__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"key_prefix","in":"path","required":true,"schema":{"type":"string","title":"Key Prefix"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/audit/log":{"post":{"tags":["Audit"],"summary":"Log an audit event (fire-and-forget)","operationId":"log_audit_event_api_v1_audit_log_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditLogRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditLogResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}}},"components":{"schemas":{"ApproveRequest":{"properties":{"thread_id":{"type":"string","title":"Thread Id","example":"thread-123"}},"type":"object","required":["thread_id"],"title":"ApproveRequest"},"ApproveResponse":{"properties":{"detail":{"type":"string","title":"Detail","description":"Human-readable result.","default":"Execution approved"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id","description":"Echoes X-Request-Id header or a server-generated UUID."}},"type":"object","title":"ApproveResponse","example":{"detail":"Execution approved","request_id":"a1b2c3d4-..."}},"AuditLogRequest":{"properties":{"event_id":{"type":"string","title":"Event Id","description":"Unique event ID for idempotency.","example":"abc123"},"source":{"type":"string","title":"Source","description":"System sending the event.","example":"plan200_mt5"},"action":{"type":"string","title":"Action","description":"What happened.","example":"trade_executed"},"payload":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Payload"}},"type":"object","required":["event_id","source","action"],"title":"AuditLogRequest"},"AuditLogResponse":{"properties":{"status":{"type":"string","title":"Status"},"event_id":{"type":"string","title":"Event Id"},"logged_at":{"type":"string","title":"Logged At"}},"type":"object","required":["status","event_id","logged_at"],"title":"AuditLogResponse"},"CheckoutRequest":{"properties":{"plan":{"type":"string","title":"Plan","description":"Target plan: starter, pro, or enterprise."}},"type":"object","required":["plan"],"title":"CheckoutRequest"},"CheckoutResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"CheckoutResponse"},"ErrorResponse":{"properties":{"detail":{"type":"string","title":"Detail"}},"type":"object","required":["detail"],"title":"ErrorResponse"},"ExecutionStatusResponse":{"properties":{"thread_id":{"type":"string","title":"Thread Id","description":"The execution thread identifier."},"status":{"type":"string","title":"Status","description":"HITL status: WAITING_APPROVAL | APPROVED | REJECTED."},"idempotency_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency Status","description":"Internal idempotency state: PENDING | COMMITTED | FAILED."},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id","description":"Echoes X-Request-Id header or a server-generated UUID."}},"type":"object","required":["thread_id","status"],"title":"ExecutionStatusResponse","example":{"idempotency_status":"COMMITTED","request_id":"a1b2c3d4-...","status":"APPROVED","thread_id":"thread-123"}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"KeyMetadata":{"properties":{"key_prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Prefix"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["key_prefix","is_active","created_at"],"title":"KeyMetadata"},"PlanInfo":{"properties":{"name":{"type":"string","title":"Name","description":"Plan identifier (free/starter/pro/enterprise)."},"display_name":{"type":"string","title":"Display Name","description":"Human-readable plan name."},"price_per_event_cents":{"type":"integer","title":"Price Per Event Cents","description":"USD cents charged per billable event."},"monthly_quota":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Monthly Quota","description":"Monthly event quota. null = unlimited."}},"type":"object","required":["name","display_name","price_per_event_cents"],"title":"PlanInfo"},"PlansResponse":{"properties":{"plans":{"items":{"$ref":"#/components/schemas/PlanInfo"},"type":"array","title":"Plans"}},"type":"object","required":["plans"],"title":"PlansResponse"},"PortalResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"PortalResponse"},"RejectRequest":{"properties":{"thread_id":{"type":"string","title":"Thread Id","example":"thread-123"}},"type":"object","required":["thread_id"],"title":"RejectRequest"},"RejectResponse":{"properties":{"detail":{"type":"string","title":"Detail","description":"Human-readable result.","default":"Execution rejected"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id","description":"Echoes X-Request-Id header or a server-generated UUID."}},"type":"object","title":"RejectResponse","example":{"detail":"Execution rejected","request_id":"a1b2c3d4-..."}},"SignupRequest":{"properties":{"email":{"type":"string","title":"Email"},"name":{"type":"string","title":"Name"}},"type":"object","required":["email","name"],"title":"SignupRequest"},"SignupResponse":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"api_key":{"type":"string","title":"Api Key"},"message":{"type":"string","title":"Message"}},"type":"object","required":["tenant_id","api_key","message"],"title":"SignupResponse"},"TenantResponse":{"properties":{"id":{"type":"string","title":"Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"type":"string","title":"Name"},"plan":{"type":"string","title":"Plan"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","email","name","plan","is_active"],"title":"TenantResponse"},"UsageSummary":{"properties":{"tenant_id":{"type":"string","title":"Tenant Id"},"period_start":{"type":"string","title":"Period Start","description":"ISO-8601 UTC start of the billing period."},"period_end":{"type":"string","title":"Period End","description":"ISO-8601 UTC end of the billing period (now)."},"events_count":{"type":"integer","title":"Events Count","description":"Total billable events in the period."},"total_cost_cents":{"type":"integer","title":"Total Cost Cents","description":"Total cost in USD cents."},"total_cost_usd":{"type":"number","title":"Total Cost Usd","description":"Total cost in USD."},"plan":{"$ref":"#/components/schemas/PlanInfo"},"quota_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Quota Remaining","description":"Events remaining before quota is reached. null = unlimited."}},"type":"object","required":["tenant_id","period_start","period_end","events_count","total_cost_cents","total_cost_usd","plan"],"title":"UsageSummary","example":{"events_count":42,"period_end":"2024-07-15T10:30:00Z","period_start":"2024-07-01T00:00:00Z","plan":{"display_name":"Starter","monthly_quota":1000,"name":"starter","price_per_event_cents":5},"quota_remaining":958,"tenant_id":"tenant_abc123","total_cost_cents":210,"total_cost_usd":2.1}},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}},"tags":[{"name":"HITL Public","description":"Stable, versioned endpoints for external integrators."}]}