{"openapi":"3.1.0","info":{"title":"Gheima API","version":"1.0.0","description":"Public REST API for the Gheima platform. Bearer-authenticated with an account API key. List endpoints are cursor-paginated; errors use a consistent envelope."},"servers":[{"url":"https://api.gheima.ma/v1"},{"url":"https://gheima.ma/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"gh_ API key"}},"responses":{"Unauthorized":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Validation":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]},"Account":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"plan":{"type":"string"},"type":{"type":"string"},"role":{"type":"string"}}},"Service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string","enum":["WEB","WORKER","STATIC"]},"status":{"type":"string"},"url":{"type":"string"},"branch":{"type":"string"}}},"Deployment":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["AWAITING_CHECKS","QUEUED","BUILDING","PUSHING","DEPLOYING","LIVE","FAILED","CANCELLED","SKIPPED"],"description":"AWAITING_CHECKS and SKIPPED occur only on services with waitForChecks: a push waits for the commit's GitHub checks, and is SKIPPED (see errorMessage) when they fail or time out."},"commitSha":{"type":["string","null"]},"commitMessage":{"type":["string","null"]},"errorMessage":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"finishedAt":{"type":["string","null"],"format":"date-time"}}},"Project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"serviceCount":{"type":"integer"}}},"Database":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"isBranch":{"type":"boolean"}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time"}}},"LogEntry":{"type":"object","properties":{"timestamp":{"type":"string"},"line":{"type":"string"}}},"ActivityEvent":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string"},"actorName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"metadata":{"type":"object"}}},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"lastStatus":{"type":["integer","null"]},"lastDeliveryAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}},"paths":{"/account":{"get":{"operationId":"account.get","summary":"Get the key’s account","description":"`role` is the role this key acts as: its creator’s live role, capped at ADMIN. `aiAvailable` says whether the PLATFORM has AI configured, not whether this account opted in.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"account":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string"},"plan":{"type":"string"},"require2fa":{"type":"boolean"},"aiOptIn":{"type":"boolean"},"role":{"type":"string"},"aiAvailable":{"type":"boolean"}},"required":["id","name","slug","type","plan","require2fa","aiOptIn","role","aiAvailable"]}},"required":["account"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"account:read","x-gheima-access":"read"}},"/account/ai-opt-in":{"put":{"operationId":"account.setAiOptIn","summary":"Turn the account’s AI features on or off","description":"Opting in lets deployment failures be sent for diagnosis. `aiAvailable` on `GET /account` says whether the platform has AI configured at all.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"account:write","x-gheima-access":"admin","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"aiOptIn":{"type":"boolean"}},"required":["aiOptIn"]}}}}}},"/account/export":{"get":{"operationId":"account.export","summary":"Everything this account holds, in one document","description":"The account, its owner, projects, services, databases, buckets, domains, invoices, members and invites. Intended for a data-portability request, so the shape follows the records rather than a curated view.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"account:read","x-gheima-access":"admin"}},"/account/spend-cap":{"get":{"operationId":"account.spendCap","summary":"Get the spend cap and this month’s spend","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"spendCapMad":{"anyOf":[{"type":"integer"},{"type":"null"}]},"spendAlertPct":{"anyOf":[{"type":"integer"},{"type":"null"}]},"currentSpendMad":{"type":"number"}},"required":["spendCapMad","spendAlertPct","currentSpendMad"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"account:read","x-gheima-access":"read"},"put":{"operationId":"account.setSpendCap","summary":"Set or clear the spend cap and its alert threshold","description":"Null clears. Both fields are required so neither is changed by omission.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"account:write","x-gheima-access":"admin","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"spendCapMad":{"anyOf":[{"type":"integer","minimum":0,"maximum":10000000},{"type":"null"}]},"spendAlertPct":{"anyOf":[{"type":"integer","minimum":1,"maximum":100},{"type":"null"}]}},"required":["spendCapMad","spendAlertPct"]}}}}}},"/activity":{"get":{"operationId":"activity.list","summary":"Account activity feed","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"entityType","in":"query","schema":{"type":"string"}},{"name":"entityId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"action":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string"},"metadata":{},"actorName":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","action","entityType","entityId","metadata","actorName","createdAt"]}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"activity:read","x-gheima-access":"read"}},"/alerts":{"get":{"operationId":"alerts.list","summary":"List alert rules","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"metric":{"type":"string","enum":["CPU_CORES","MEMORY_MB","SERVICE_DOWN"]},"comparator":{"type":"string","enum":["GT","LT"]},"threshold":{"type":"number"},"enabled":{"type":"boolean"},"state":{"type":"string"},"lastValue":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastCheckedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"serviceId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"serviceName":{"anyOf":[{"type":"string"},{"type":"null"}]},"channelId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"channelName":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","metric","comparator","threshold","enabled","state","lastValue","lastCheckedAt","serviceId","serviceName","channelId","channelName"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"alerts:read","x-gheima-access":"read"},"post":{"operationId":"alerts.create","summary":"Create an alert rule","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"alert":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}},"required":["alert"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"alerts:write","x-gheima-access":"admin","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"metric":{"type":"string","enum":["CPU_CORES","MEMORY_MB","SERVICE_DOWN"]},"comparator":{"type":"string","enum":["GT","LT"]},"threshold":{"type":"number"},"serviceId":{"type":"string","format":"uuid"}},"required":["name","metric","comparator","threshold"]}}}}}},"/alerts/{id}":{"patch":{"operationId":"alerts.update","summary":"Update an alert rule","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"alerts:write","x-gheima-access":"admin","x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"threshold":{"type":"number"},"comparator":{"type":"string","enum":["GT","LT"]},"enabled":{"type":"boolean"},"name":{"type":"string","minLength":1,"maxLength":80}}}}}}},"delete":{"operationId":"alerts.delete","summary":"Delete an alert rule","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"alerts:write","x-gheima-access":"admin"}},"/alerts/{id}/events":{"get":{"operationId":"alerts.events","summary":"Recent state changes for an alert rule","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"state":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","state","value","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"alerts:read","x-gheima-access":"read"}},"/alerts/preview":{"get":{"operationId":"alerts.preview","summary":"Read a metric’s current value before creating a rule","description":"Lets you pick a threshold against what the service is doing right now.","parameters":[{"name":"metric","in":"query","required":true,"schema":{"type":"string","enum":["CPU_CORES","MEMORY_MB","SERVICE_DOWN"]}},{"name":"serviceId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["value"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"alerts:read","x-gheima-access":"read"}},"/api-keys":{"get":{"operationId":"apiKeys.list","summary":"List the account’s API keys","description":"The secret is never returned, only the prefix that identifies a key.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"ipAllowlist":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"revokedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["id","name","prefix","scopes","ipAllowlist","lastUsedAt","createdAt","revokedAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"api-keys:read","x-gheima-access":"read","x-gheima-sensitive":true},"post":{"operationId":"apiKeys.create","summary":"Create an API key","description":"The plaintext `key` is returned ONCE and never stored. Omitting `scopes` grants full access; otherwise use coarse (`read`, `write`) or granular (`services:write`) scopes. Note that a coarse `write` cannot reach the sensitive resources.","responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"apiKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"prefix":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"scopes":{"type":"array","items":{"type":"string"}},"ipAllowlist":{"type":"array","items":{"type":"string"}},"key":{"type":"string"}},"required":["id","name","prefix","createdAt","scopes","ipAllowlist","key"]}},"required":["apiKey"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"api-keys:write","x-gheima-access":"admin","x-gheima-sensitive":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"scopes":{"maxItems":20,"type":"array","items":{"type":"string","maxLength":40}},"ipAllowlist":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":64}}},"required":["name"]}}}}}},"/api-keys/{id}/revoke":{"post":{"operationId":"apiKeys.revoke","summary":"Revoke an API key","description":"Irreversible. Revoking an already-revoked key succeeds.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"api-keys:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true}},"/audit":{"get":{"operationId":"audit.list","summary":"The account’s audit log","description":"Every entry names the surface it came through (DASHBOARD, API, CLI, MCP or SYSTEM), so an action taken with a key is distinguishable from the same action taken by a person in the dashboard.","parameters":[{"name":"action","in":"query","schema":{"type":"string","maxLength":120}},{"name":"entityType","in":"query","schema":{"type":"string","maxLength":60}},{"name":"entityId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"userId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"cursor","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"default":50,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"action":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string"},"actorName":{"anyOf":[{"type":"string"},{"type":"null"}]},"surface":{"type":"string"},"apiKeyId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"ipAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","action","entityType","entityId","actorName","surface","apiKeyId","ipAddress","createdAt"]}},"nextCursor":{"type":"string","format":"uuid"}},"required":["items"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"audit:read","x-gheima-access":"admin"}},"/audit/entity-types":{"get":{"operationId":"audit.entityTypes","summary":"Distinct entity types present in the audit log","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"string"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"audit:read","x-gheima-access":"admin"}},"/audit/export":{"get":{"operationId":"audit.export","summary":"Export the audit log (CSV or JSON)","parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["csv","json"]}},{"name":"action","in":"query","schema":{"type":"string"}},{"name":"entityType","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/billing/auto-renew":{"post":{"operationId":"billing.setAutoRenew","summary":"Turn credit-funded auto-renewal on or off","description":"The only recurrence a one-shot gateway allows: credit already topped up buys the next period with no payment step. Stripe subscriptions renew themselves and are managed in the provider’s portal.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"autoRenew":{"type":"boolean"}},"required":["autoRenew"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]}}}}}},"/billing/cancel":{"post":{"operationId":"billing.cancelPlan","summary":"Cancel at the end of the period already paid for, or undo that","description":"Immediate cancellation is deliberately not offered: on a one-shot gateway the window is already paid for and cannot be refunded, so ending it early would simply take the customer’s money. Reversible until the date they bought.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"cancelAtPeriodEnd":{"type":"boolean"},"currentPeriodEnd":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["cancelAtPeriodEnd","currentPeriodEnd"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cancel":{"type":"boolean"}},"required":["cancel"]}}}}}},"/billing/identity":{"get":{"operationId":"billing.identity","summary":"The billing identity that goes on invoices","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"accountName":{"type":"string"},"billingEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingName":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingIce":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingTaxId":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingRc":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["accountName","billingEmail","billingName","billingAddress","billingIce","billingTaxId","billingRc"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:read","x-gheima-access":"admin","x-gheima-sensitive":true},"put":{"operationId":"billing.setIdentity","summary":"Update the billing identity","description":"Affects invoices issued from here on. A blank field clears the line rather than storing an empty string.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"billingEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingName":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingIce":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingTaxId":{"anyOf":[{"type":"string"},{"type":"null"}]},"billingRc":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["billingEmail","billingName","billingAddress","billingIce","billingTaxId","billingRc"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"billingEmail":{"anyOf":[{"type":"string","maxLength":320,"format":"email"},{"type":"null"}]},"billingName":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"billingAddress":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"billingIce":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}]},"billingTaxId":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}]},"billingRc":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}]}}}}}}}},"/billing/invoices":{"get":{"operationId":"billing.invoices","summary":"List invoices, newest first","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"anyOf":[{"type":"string"},{"type":"null"}]},"amountMad":{"type":"number"},"status":{"type":"string"},"plan":{"anyOf":[{"type":"string"},{"type":"null"}]},"term":{"anyOf":[{"type":"string"},{"type":"null"}]},"provider":{"anyOf":[{"type":"string"},{"type":"null"}]},"hostedUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"pdfUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"periodStart":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"servicePeriodStart":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"servicePeriodEnd":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"lines":{"type":"array","items":{"type":"object","properties":{"meter":{"anyOf":[{"type":"string"},{"type":"null"}]},"quantity":{"type":"number"},"unitPriceMad":{"type":"number"},"amountMad":{"type":"number"}},"required":["meter","quantity","unitPriceMad","amountMad"]}}},"required":["id","number","amountMad","status","plan","term","provider","hostedUrl","pdfUrl","periodStart","servicePeriodStart","servicePeriodEnd","createdAt","lines"]}},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["rows","nextCursor"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:read","x-gheima-access":"admin","x-gheima-sensitive":true}},"/billing/invoices/{id}":{"get":{"operationId":"billing.invoice","summary":"One invoice in full","description":"Carries the billing identity SNAPSHOT taken when the document was issued, so correcting your details later does not rewrite an invoice already filed.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"anyOf":[{"type":"string"},{"type":"null"}]},"amountMad":{"type":"number"},"status":{"type":"string"},"plan":{"anyOf":[{"type":"string"},{"type":"null"}]},"term":{"anyOf":[{"type":"string"},{"type":"null"}]},"provider":{"anyOf":[{"type":"string"},{"type":"null"}]},"hostedUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"pdfUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"periodStart":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"servicePeriodStart":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"servicePeriodEnd":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"lines":{"type":"array","items":{"type":"object","properties":{"meter":{"anyOf":[{"type":"string"},{"type":"null"}]},"quantity":{"type":"number"},"unitPriceMad":{"type":"number"},"amountMad":{"type":"number"}},"required":["meter","quantity","unitPriceMad","amountMad"]}},"subtotalMinor":{"anyOf":[{"type":"integer"},{"type":"null"}]},"taxMinor":{"anyOf":[{"type":"integer"},{"type":"null"}]},"taxRateBp":{"anyOf":[{"type":"integer"},{"type":"null"}]},"seller":{},"buyer":{},"totalMad":{"type":"number"},"subtotalMad":{"type":"number"},"taxMad":{"type":"number"}},"required":["id","number","amountMad","status","plan","term","provider","hostedUrl","pdfUrl","periodStart","servicePeriodStart","servicePeriodEnd","createdAt","lines","subtotalMinor","taxMinor","taxRateBp","seller","buyer","totalMad","subtotalMad","taxMad"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:read","x-gheima-access":"admin","x-gheima-sensitive":true}},"/billing/ledger":{"get":{"operationId":"billing.ledger","summary":"The account’s credit statement","description":"Every movement in and out of the account’s credit: the running account behind the invoices.","parameters":[{"name":"limit","in":"query","schema":{"default":25,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"amountMinor":{"type":"integer"},"meter":{"anyOf":[{"type":"string"},{"type":"null"}]},"quantity":{"anyOf":[{"type":"string"},{"type":"null"}]},"periodStart":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"provider":{"anyOf":[{"type":"string"},{"type":"null"}]},"providerTxnId":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","kind","amountMinor","meter","quantity","periodStart","provider","providerTxnId","description","createdAt"]}},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["rows","nextCursor"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:read","x-gheima-access":"admin","x-gheima-sensitive":true}},"/billing/low-balance-alert":{"put":{"operationId":"billing.setLowBalanceAlert","summary":"Set the balance at which the account is warned it is running low","description":"Null clears the warning, and the account then goes straight from HEALTHY to EMPTY. `rechargeMad` is rejected on a gateway that cannot charge a saved card.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"autoRechargeAtMinor":{"anyOf":[{"type":"integer"},{"type":"null"}]},"autoRechargeMinor":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["autoRechargeAtMinor","autoRechargeMinor"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"thresholdMad":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]},"rechargeMad":{"anyOf":[{"type":"number","exclusiveMinimum":0},{"type":"null"}]}},"required":["thresholdMad"]}}}}}},"/billing/overage":{"get":{"operationId":"billing.overage","summary":"Plan allowances, the overage budget, and what happens at the limit","description":"Month-to-date use of each included allowance (bandwidth, build minutes, object storage, and Moroccan bandwidth on a residency tier). Past an allowance, a paid plan may buy more from its credit up to `budgetMinor` a month; the default 0 is a hard limit. CPU and memory are inside the plan and are never charged as overage. `enabled` is false while overage billing is not switched on for this deployment: nothing is charged or refused then.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"applies":{"type":"boolean"},"eligible":{"type":"boolean"},"budgetMinor":{"type":"integer"},"spentMinor":{"type":"integer"},"budgetRemainingMinor":{"type":"integer"},"balanceMinor":{"type":"integer"},"canBuyOverage":{"type":"boolean"},"meters":{"type":"array","items":{"type":"object","properties":{"meter":{"type":"string"},"used":{"type":"number"},"included":{"type":"number"},"unit":{"type":"string"},"pct":{"type":"number"},"overageMinor":{"type":"integer"},"rateMicroSantimat":{"type":"integer"},"exhausted":{"type":"boolean"},"limitReached":{"type":"boolean"},"blocked":{"type":"boolean"},"enforcement":{"type":"string"}},"required":["meter","used","included","unit","pct","overageMinor","rateMicroSantimat","exhausted","limitReached","blocked","enforcement"]}}},"required":["enabled","applies","eligible","budgetMinor","spentMinor","budgetRemainingMinor","balanceMinor","canBuyOverage","meters"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:read","x-gheima-access":"read","x-gheima-sensitive":true}},"/billing/overage-budget":{"put":{"operationId":"billing.setOverageBudget","summary":"Set the monthly overage budget","description":"The most this account may spend from its credit on usage past its plan allowances in a month. 0 is a hard limit. Charges stop at the budget or the balance, whichever runs out first, and nothing is billed after that. Refused on FREE and SCHOOL.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"budgetMinor":{"type":"integer"}},"required":["budgetMinor"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"budgetMad":{"type":"number","minimum":0}},"required":["budgetMad"]}}}}}},"/billing/plan":{"post":{"operationId":"billing.changePlan","summary":"Change plan, or re-pay the current one","description":"Returns a checkout `url` to complete. This call charges nobody by itself. A same-term move to a CHEAPER plan settles in place instead (`switched: true`): it takes no money and converts time already paid for onto the new plan.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"carriedDays":{"type":"number"},"switched":{"type":"boolean"},"currentPeriodEnd":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"priceMad":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["url","carriedDays","switched","currentPeriodEnd","priceMad"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:write","x-gheima-access":"admin","x-gheima-sensitive":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["FREE","DEV","PRO","TEAM","AGENCY","SCHOOL"]},"term":{"default":"MONTHLY","type":"string","enum":["MONTHLY","QUARTERLY","ANNUAL"]}},"required":["plan"]}}}}}},"/billing/subscription":{"get":{"operationId":"billing.current","summary":"The current subscription","description":"`termsEnabled` says whether this deployment offers anything beyond monthly billing.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"subscription":{"anyOf":[{"type":"object","properties":{"plan":{"type":"string"},"status":{"type":"string"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}]},"term":{"anyOf":[{"type":"string"},{"type":"null"}]},"autoRenew":{"type":"boolean"},"currentPeriodEnd":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"cancelAtPeriodEnd":{"type":"boolean"},"graceUntil":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["plan","status","provider","term","autoRenew","currentPeriodEnd","cancelAtPeriodEnd","graceUntil"]},{"type":"null"}]},"hasCustomer":{"type":"boolean"},"termsEnabled":{"type":"boolean"}},"required":["subscription","hasCustomer","termsEnabled"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:read","x-gheima-access":"read","x-gheima-sensitive":true}},"/billing/topup":{"post":{"operationId":"billing.createTopup","summary":"Start a credit top-up","description":"Returns a checkout `url`. No money moves until a human completes it, and the amount is bounded by the same limits the dashboard enforces.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"amountMinor":{"type":"integer"}},"required":["url","amountMinor"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:write","x-gheima-access":"admin","x-gheima-sensitive":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amountMad":{"type":"number","exclusiveMinimum":0}},"required":["amountMad"]}}}}}},"/billing/wallet":{"get":{"operationId":"billing.wallet","summary":"Credit balance and where it sits on the enforcement ladder","description":"`canAutoRecharge` is false on a gateway that cannot charge a saved card, which is every Moroccan one. A low balance then warns rather than tops itself up.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"billingMode":{"type":"string"},"purpose":{"type":"string"},"balanceMinor":{"type":"integer"},"autoRechargeMinor":{"anyOf":[{"type":"integer"},{"type":"null"}]},"autoRechargeAtMinor":{"anyOf":[{"type":"integer"},{"type":"null"}]},"canAutoRecharge":{"type":"boolean"},"status":{"type":"string"},"fundsOverage":{"type":"boolean"}},"required":["billingMode","purpose","balanceMinor","autoRechargeMinor","autoRechargeAtMinor","canAutoRecharge","status","fundsOverage"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"billing:read","x-gheima-access":"read","x-gheima-sensitive":true}},"/channels":{"get":{"operationId":"channels.list","summary":"List notification channels","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["EMAIL","WEBHOOK"]},"target":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["DEPLOY_SUCCESS","DEPLOY_FAILED","DEPLOY_SKIPPED","MEMBER_JOINED","LIMIT_WARNING","SSL_EXPIRING","BILLING_PAST_DUE","BILLING_RENEWAL_DUE"]}},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"hasSecret":{"type":"boolean"}},"required":["id","type","target","events","enabled","createdAt","hasSecret"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"channels:read","x-gheima-access":"read","x-gheima-sensitive":true},"post":{"operationId":"channels.create","summary":"Create a notification channel","description":"An EMAIL target must be an email address and a WEBHOOK target a URL. Webhook deliveries are signed when a secret is supplied, and always fetched through the SSRF guard.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"channels:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["EMAIL","WEBHOOK"]},"target":{"type":"string","minLength":1,"maxLength":500},"events":{"default":[],"type":"array","items":{"type":"string","enum":["DEPLOY_SUCCESS","DEPLOY_FAILED","DEPLOY_SKIPPED","MEMBER_JOINED","LIMIT_WARNING","SSL_EXPIRING","BILLING_PAST_DUE","BILLING_RENEWAL_DUE"]}},"secret":{"type":"string","maxLength":200}},"required":["type","target"]}}}}}},"/channels/{id}":{"patch":{"operationId":"channels.update","summary":"Update a channel’s events or enabled state","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"channels:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"string","enum":["DEPLOY_SUCCESS","DEPLOY_FAILED","DEPLOY_SKIPPED","MEMBER_JOINED","LIMIT_WARNING","SSL_EXPIRING","BILLING_PAST_DUE","BILLING_RENEWAL_DUE"]}},"enabled":{"type":"boolean"}}}}}}},"delete":{"operationId":"channels.delete","summary":"Delete a notification channel","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"channels:write","x-gheima-access":"admin","x-gheima-sensitive":true}},"/channels/{id}/deliveries":{"get":{"operationId":"channels.deliveries","summary":"List recent delivery attempts for a channel","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"event":{"type":"string"},"title":{"type":"string"},"success":{"type":"boolean"},"statusCode":{"anyOf":[{"type":"integer"},{"type":"null"}]},"error":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","event","title","success","statusCode","error","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"channels:read","x-gheima-access":"read","x-gheima-sensitive":true}},"/channels/{id}/test":{"post":{"operationId":"channels.test","summary":"Send a test delivery to a channel","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"channels:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true}},"/channels/deliveries/{deliveryId}/retry":{"post":{"operationId":"channels.retry","summary":"Re-send a past delivery","parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"channels:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true}},"/cron":{"get":{"operationId":"cron.list","summary":"List cron jobs","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"schedule":{"type":"string"},"timezone":{"type":"string"},"enabled":{"type":"boolean"},"serviceId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"lastRunAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"nextRunAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"lastStatus":{"anyOf":[{"type":"string","enum":["QUEUED","RUNNING","SUCCESS","FAILED","SKIPPED"]},{"type":"null"}]}},"required":["id","name","schedule","timezone","enabled","serviceId","lastRunAt","nextRunAt","lastStatus"]}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:read","x-gheima-access":"read"},"post":{"operationId":"cron.create","summary":"Create a cron job","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"cronJob":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}},"required":["cronJob"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"schedule":{"type":"string","minLength":1,"maxLength":120},"command":{"type":"string","minLength":1,"maxLength":4000},"serviceId":{"type":"string","format":"uuid"},"timezone":{"type":"string","minLength":1,"maxLength":64},"timeoutSeconds":{"type":"integer","minimum":1,"maximum":3600}},"required":["name","schedule","command"]}}}}}},"/cron/{id}":{"get":{"operationId":"cron.get","summary":"Get a cron job","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"cronJob":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"schedule":{"type":"string"},"timezone":{"type":"string"},"enabled":{"type":"boolean"},"serviceId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"lastRunAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"nextRunAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"lastStatus":{"anyOf":[{"type":"string","enum":["QUEUED","RUNNING","SUCCESS","FAILED","SKIPPED"]},{"type":"null"}]},"command":{"type":"string"},"timeoutSeconds":{"type":"integer"},"lastExitCode":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["id","name","schedule","timezone","enabled","serviceId","lastRunAt","nextRunAt","lastStatus","command","timeoutSeconds","lastExitCode"]}},"required":["cronJob"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:read","x-gheima-access":"read"},"patch":{"operationId":"cron.update","summary":"Update a cron job","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"schedule":{"type":"string","minLength":1,"maxLength":120},"command":{"type":"string","minLength":1,"maxLength":4000},"serviceId":{"type":"string","format":"uuid"},"timezone":{"type":"string","minLength":1,"maxLength":64},"timeoutSeconds":{"type":"integer","minimum":1,"maximum":3600}}}}}}},"delete":{"operationId":"cron.delete","summary":"Delete a cron job","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:write","x-gheima-access":"admin"}},"/cron/{id}/run":{"post":{"operationId":"cron.run","summary":"Trigger a cron job now","description":"Queues an out-of-schedule run. Returns 202 as soon as the run is queued. Poll `GET /cron/{id}/runs` for the outcome.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:write","x-gheima-access":"write","x-gheima-idempotent":true,"x-gheima-rate-limit":{"action":"cron-run","max":20,"windowMs":60000}}},"/cron/{id}/runs":{"get":{"operationId":"cron.runs","summary":"List recent runs of a cron job","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["QUEUED","RUNNING","SUCCESS","FAILED","SKIPPED"]},"startedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"finishedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"exitCode":{"anyOf":[{"type":"integer"},{"type":"null"}]},"durationMs":{"anyOf":[{"type":"integer"},{"type":"null"}]},"hasLog":{"type":"boolean"}},"required":["id","status","startedAt","finishedAt","exitCode","durationMs","hasLog"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:read","x-gheima-access":"read"}},"/cron/{id}/runs/{runId}/logs":{"get":{"operationId":"cron.runLogs","summary":"Read the captured log of one cron run","description":"Returns an empty string when the run captured no log.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"runId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"logs":{"type":"string"}},"required":["logs"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:read","x-gheima-access":"read"}},"/cron/{id}/toggle":{"post":{"operationId":"cron.toggle","summary":"Enable or disable a cron job","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"cron:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]}}}}}},"/databases":{"get":{"operationId":"databases.list","summary":"List managed databases","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"type":"string","enum":["POSTGRES","REDIS","MYSQL","MONGODB"]},"status":{"type":"string"},"isBranch":{"type":"boolean"}},"required":["id","name","type","status","isBranch"]}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:read","x-gheima-access":"read"},"post":{"operationId":"databases.create","summary":"Create a managed database","description":"Provisioned in the background; poll until its status is RUNNING.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"databaseId":{"type":"string","format":"uuid"},"serviceId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]}},"required":["databaseId","serviceId"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"type":{"type":"string","enum":["POSTGRES","REDIS","MYSQL","MONGODB"]},"regionCode":{"type":"string","maxLength":32}},"required":["name","type"]}}}}}},"/databases/{id}":{"get":{"operationId":"databases.get","summary":"Get a managed database","description":"`databaseName` is the physical database on the managed instance, the path segment of a connection string. It is null until provisioning has claimed the row.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"database":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"databaseName":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"type":"string","enum":["POSTGRES","REDIS","MYSQL","MONGODB"]},"status":{"type":"string"},"host":{"anyOf":[{"type":"string"},{"type":"null"}]},"port":{"anyOf":[{"type":"integer"},{"type":"null"}]},"username":{"anyOf":[{"type":"string"},{"type":"null"}]},"storageMb":{"type":"integer"}},"required":["id","name","databaseName","type","status","host","port","username","storageMb"]}},"required":["database"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:read","x-gheima-access":"read"},"delete":{"operationId":"databases.delete","summary":"Deprovision a managed database","description":"The data goes with it.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"admin"}},"/databases/{id}/backup-schedule":{"get":{"operationId":"databases.getBackupSchedule","summary":"Get a database’s backup schedule","description":"Scheduled backups are Postgres-only; `supported` says so for other engines.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"supported":{"type":"boolean"},"retentionMax":{"type":"integer"},"schedule":{"anyOf":[{"type":"object","properties":{"schedule":{"type":"string"},"timezone":{"type":"string"},"retentionCount":{"type":"integer"},"enabled":{"type":"boolean"},"lastRunAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"nextRunAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"lastStatus":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["schedule","timezone","retentionCount","enabled","lastRunAt","nextRunAt","lastStatus"]},{"type":"null"}]}},"required":["supported","retentionMax","schedule"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:read","x-gheima-access":"read"},"put":{"operationId":"databases.setBackupSchedule","summary":"Set a database’s backup schedule","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"retentionCount":{"type":"integer"}},"required":["ok","retentionCount"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schedule":{"type":"string","minLength":1,"maxLength":120},"timezone":{"default":"UTC","type":"string","minLength":1,"maxLength":64},"retentionCount":{"type":"integer","minimum":1,"maximum":365},"enabled":{"default":true,"type":"boolean"}},"required":["schedule","retentionCount"]}}}}},"delete":{"operationId":"databases.deleteBackupSchedule","summary":"Stop scheduled backups","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write"}},"/databases/{id}/branches":{"get":{"operationId":"databases.branches","summary":"List a database’s branches","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","status","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:read","x-gheima-access":"read"},"post":{"operationId":"databases.createBranch","summary":"Branch a database","description":"A copy of the data at this moment, provisioned in the background.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60}},"required":["name"]}}}}}},"/databases/{id}/branches/{branchId}":{"delete":{"operationId":"databases.deleteBranch","summary":"Delete a branch","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"branchId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write"}},"/databases/{id}/branches/{branchId}/reset":{"post":{"operationId":"databases.resetBranch","summary":"Reset a branch to its parent’s current data","description":"Queued, and it discards everything written to the branch since.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"branchId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write","x-gheima-idempotent":true}},"/databases/{id}/extensions":{"get":{"operationId":"databases.extensions","summary":"List the Postgres extensions available and installed","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"label":{"type":"string"},"installed":{"type":"boolean"}},"required":["name","label","installed"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:read","x-gheima-access":"read"},"post":{"operationId":"databases.enableExtension","summary":"Enable a Postgres extension","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"name":{"type":"string"}},"required":["ok","name"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","enum":["vector"]}},"required":["name"]}}}}}},"/databases/{id}/metrics":{"get":{"operationId":"databases.metrics","summary":"Engine metrics for a managed database","description":"Size, connections, transaction rate, cache hit and deadlocks. These are the ENGINE’s own metrics, not the container’s, because a managed database is a logical object on a shared instance. `supported` is false for Redis, which has no per-database exporter; `configured` is false where the deployment has no metrics backend.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"minutes","in":"query","schema":{"default":30,"type":"integer","minimum":5,"maximum":360}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"configured":{"type":"boolean"},"supported":{"type":"boolean"},"series":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"unit":{"type":"string"},"points":{"type":"array","items":{"type":"object","properties":{"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"]}}},"required":["key","unit","points"]}}},"required":["configured","supported","series"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:read","x-gheima-access":"read"}},"/databases/{id}/query":{"post":{"operationId":"databases.query","summary":"Run a statement against a managed database","description":"Arbitrary SQL (or a Redis command line) against the tenant’s own database. Rows are capped and `notice` says when a result was truncated. A statement that fails comes back as a 400 carrying the engine’s own message.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"type":"object","properties":{"columns":{"type":"array","items":{"type":"string"}},"rows":{"type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"rowCount":{"type":"integer"},"notice":{"type":"string"}},"required":["columns","rows","rowCount"]}},"required":["result"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write","x-gheima-sensitive":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"statement":{"type":"string","minLength":1,"maxLength":20000}},"required":["statement"]}}}}}},"/databases/{id}/query-activity":{"get":{"operationId":"databases.queryActivity","summary":"Top statements by cumulative time","description":"Postgres only, and only where `pg_stat_statements` is installed. `reason` says which of the two is missing. Statements are NORMALISED by the extension, so constants appear as $1, $2 rather than the values a query ran with.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"available":{"type":"boolean"},"reason":{"type":"string","enum":["engine","extension"]},"rows":{"type":"array","items":{"type":"object","properties":{"query":{"type":"string"},"calls":{"type":"number"},"totalMs":{"type":"number"},"meanMs":{"type":"number"},"rows":{"type":"number"}},"required":["query","calls","totalMs","meanMs","rows"]}}},"required":["available","rows"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:read","x-gheima-access":"read"}},"/databases/{id}/reset-password":{"post":{"operationId":"databases.resetPassword","summary":"Rotate a database’s password","description":"Queued. Anything still using the old password stops working once it lands.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true}},"/databases/{id}/reveal":{"post":{"operationId":"databases.reveal","summary":"Reveal a database’s connection credentials","description":"Returns a connection string with full control of the data. Postgres additionally returns a pooled (PgBouncer) string when a pooler is configured.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"connectionString":{"type":"string"},"pooledConnectionString":{"anyOf":[{"type":"string"},{"type":"null"}]},"password":{"type":"string"},"username":{"anyOf":[{"type":"string"},{"type":"null"}]},"host":{"anyOf":[{"type":"string"},{"type":"null"}]},"port":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["connectionString","pooledConnectionString","password","username","host","port"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-rate-limit":{"action":"reveal","max":30,"windowMs":60000}}},"/databases/{id}/snapshots":{"get":{"operationId":"databases.snapshots","summary":"List snapshots","description":"`automated` marks a snapshot taken by the schedule rather than by hand.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"sizeBytes":{"type":"string"},"error":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"scheduleId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"automated":{"type":"boolean"}},"required":["id","status","sizeBytes","error","createdAt","scheduleId","automated"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:read","x-gheima-access":"read"},"post":{"operationId":"databases.createSnapshot","summary":"Take a snapshot now","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write","x-gheima-idempotent":true}},"/databases/{id}/snapshots/{snapshotId}":{"delete":{"operationId":"databases.deleteSnapshot","summary":"Delete a snapshot","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"snapshotId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"write"}},"/databases/{id}/snapshots/{snapshotId}/restore":{"post":{"operationId":"databases.restoreSnapshot","summary":"Restore a database from a snapshot","description":"Queued, and it OVERWRITES the database’s current contents with the snapshot’s. There is no undo. Take a snapshot first if the current state matters.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"snapshotId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"databases:write","x-gheima-access":"admin","x-gheima-idempotent":true}},"/device/start":{"post":{"operationId":"device.start","summary":"Begin a device login (unauthenticated)","security":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"client_name":{"type":"string","description":"Shown on the approval screen, e.g. \"CLI on omar-mbp\"."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"device_code":{"type":"string"},"user_code":{"type":"string"},"verification_uri":{"type":"string"},"verification_uri_complete":{"type":"string"},"expires_in":{"type":"integer"},"interval":{"type":"integer"}}}}}},"429":{"description":"Too many login attempts from this address"}}}},"/device/token":{"post":{"operationId":"device.token","summary":"Exchange an approved device code for an API key (unauthenticated)","description":"Poll until approved. `error.code` carries the RFC 8628 values `authorization_pending`, `slow_down`, `expired_token` and `access_denied`.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["device_code"],"properties":{"device_code":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string"},"account_id":{"type":"string"},"key_name":{"type":"string"}}}}}},"400":{"description":"authorization_pending, expired_token or invalid_request"},"403":{"description":"access_denied: the sign-in was refused"},"429":{"description":"slow_down: polling faster than the given interval"}}}},"/domains/{domainId}":{"delete":{"operationId":"domains.remove","summary":"Detach a custom domain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"domains:write","x-gheima-access":"write"}},"/domains/{domainId}/verify":{"post":{"operationId":"domains.verify","summary":"Check a domain’s TXT challenge and mark it verified","description":"DNS can take a few minutes to propagate; an unfound record is a 400.","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"verified":{"type":"boolean","const":true}},"required":["verified"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"domains:write","x-gheima-access":"write","x-gheima-idempotent":true}},"/email/domains":{"get":{"operationId":"email.listDomains","summary":"List sending domains","description":"Each domain carries the DKIM and SPF records to publish.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"status":{"type":"string"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"]}}},"required":["id","domain","status","verifiedAt","records"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"email:read","x-gheima-access":"read"},"post":{"operationId":"email.addDomain","summary":"Add a sending domain","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"status":{"type":"string"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"]}}},"required":["id","domain","status","verifiedAt","records"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"email:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","minLength":3,"maxLength":253}},"required":["domain"]}}}}}},"/email/domains/{id}":{"get":{"operationId":"email.getDomain","summary":"Get a sending domain","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"status":{"type":"string"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"]}}},"required":["id","domain","status","verifiedAt","records"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"email:read","x-gheima-access":"read"},"delete":{"operationId":"email.deleteDomain","summary":"Remove a sending domain","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"email:write","x-gheima-access":"admin"}},"/email/domains/{id}/verify":{"post":{"operationId":"email.verifyDomain","summary":"Check a sending domain’s DNS records","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"verified":{"type":"boolean"},"status":{"type":"string"}},"required":["verified","status"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"email:write","x-gheima-access":"write","x-gheima-idempotent":true}},"/email/messages":{"get":{"operationId":"email.messages","summary":"Recent sent messages","parameters":[{"name":"domainId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"toAddress":{"type":"string"},"subject":{"type":"string"},"status":{"type":"string"},"error":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","toAddress","subject","status","error","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"email:read","x-gheima-access":"read"}},"/email/send":{"post":{"operationId":"email.send","summary":"Send an email from a verified domain","description":"Queued, not sent inline. The `from` address must belong to the verified domain (or a subdomain of it).","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"string","format":"uuid"},"status":{"type":"string","const":"QUEUED"}},"required":["messageId","status"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"email:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domainId":{"type":"string","format":"uuid"},"from":{"type":"string","minLength":3,"maxLength":320},"to":{"type":"string","maxLength":320,"format":"email"},"subject":{"type":"string","minLength":1,"maxLength":255},"html":{"type":"string","maxLength":500000},"text":{"type":"string","maxLength":500000}},"required":["domainId","from","to","subject"]}}}}}},"/env-groups":{"get":{"operationId":"envGroups.list","summary":"List env groups","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"variableCount":{"type":"integer"},"serviceCount":{"type":"integer"}},"required":["id","name","variableCount","serviceCount"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:read","x-gheima-access":"read"},"post":{"operationId":"envGroups.create","summary":"Create an env group","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60}},"required":["name"]}}}}}},"/env-groups/{id}":{"get":{"operationId":"envGroups.get","summary":"Get an env group’s keys and attached services","description":"Values are masked. Nothing here returns a variable’s value.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"keys":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"masked":{"type":"string"},"secret":{"type":"boolean"}},"required":["key","masked","secret"]}},"services":{"type":"array","items":{"type":"object","properties":{"serviceId":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["serviceId","name"]}}},"required":["id","name","keys","services"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:read","x-gheima-access":"read"},"put":{"operationId":"envGroups.setVars","summary":"Replace an env group’s variables","description":"Variables marked secret that `vars` does not mention are kept: they cannot be read back to resubmit. Remove one with `DELETE /env-groups/{id}/vars/{envKey}`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"count":{"type":"integer"}},"required":["ok","count"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"vars":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":32768}}},"required":["vars"]}}}}},"delete":{"operationId":"envGroups.delete","summary":"Delete an env group","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"admin"}},"/env-groups/{id}/history":{"get":{"operationId":"envGroups.history","summary":"List an env group’s history","description":"Newest first, the last 50 changes: which variable NAMES each one changed, who made it and when. Values are never returned.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"action":{"type":"string"},"changedKeys":{"type":"array","items":{"type":"string"}},"restoredFromId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"actor":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","email"]},{"type":"null"}]},"actorHidden":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","action","changedKeys","restoredFromId","actor","actorHidden","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:read","x-gheima-access":"read"}},"/env-groups/{id}/history/{revisionId}/rollback":{"post":{"operationId":"envGroups.rollback","summary":"Restore an env group to a saved revision","description":"Restores the group’s variables as they were after that revision, as a new revision. Attached services pick it up on their next deploy. Values are never returned.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"revisionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"changedKeys":{"type":"array","items":{"type":"string"}}},"required":["ok","changedKeys"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"write"}},"/env-groups/{id}/import":{"post":{"operationId":"envGroups.import","summary":"Import .env text into a group","description":"Merges by default; `replace: true` discards what was there except secret variables, which are kept. `secret: true` marks every imported variable secret. `invalidLines` gives the 1-based line numbers that could not be parsed. Those lines are skipped, not fatal.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"imported":{"type":"integer"},"total":{"type":"integer"},"invalidLines":{"type":"array","items":{"type":"integer"}}},"required":["imported","total","invalidLines"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"dotenv":{"type":"string","maxLength":200000},"replace":{"default":false,"type":"boolean"},"secret":{"type":"boolean","const":true}},"required":["dotenv"]}}}}}},"/env-groups/{id}/reveal":{"post":{"operationId":"envGroups.reveal","summary":"Reveal an env group’s values in plaintext","description":"Everything else returns masked keys. This returns values, which routinely hold credentials, so it needs ADMIN, is rate limited and audited, and a coarse `write` cannot reach it. Variables marked secret are never returned, to anyone.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"vars":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["vars"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-rate-limit":{"action":"reveal","max":30,"windowMs":60000}}},"/env-groups/{id}/services":{"post":{"operationId":"envGroups.attach","summary":"Attach an env group to a service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"serviceId":{"type":"string","format":"uuid"}},"required":["serviceId"]}}}}}},"/env-groups/{id}/services/{serviceId}":{"delete":{"operationId":"envGroups.detach","summary":"Detach an env group from a service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"serviceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"write"}},"/env-groups/{id}/vars":{"put":{"operationId":"envGroups.setVar","summary":"Create or update one variable of an env group","description":"The per-key write a group needs once some of its variables are secret and cannot be revealed and resubmitted. `secret: true` makes the variable write-only, one-way.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":200},"value":{"type":"string","maxLength":32768},"secret":{"type":"boolean","const":true}},"required":["key","value"]}}}}}},"/env-groups/{id}/vars/{envKey}":{"delete":{"operationId":"envGroups.removeVar","summary":"Remove one variable of an env group","description":"The only way a variable marked secret leaves a group.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"envKey","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"env-groups:write","x-gheima-access":"write"}},"/gitlab/connections":{"get":{"operationId":"gitlab.connections","summary":"List connected GitLab instances","description":"The stored access token is never returned.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"baseUrl":{"type":"string"},"gitlabUsername":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastUsedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","baseUrl","gitlabUsername","lastUsedAt","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"gitlab:read","x-gheima-access":"read","x-gheima-sensitive":true},"post":{"operationId":"gitlab.connect","summary":"Connect a GitLab instance with an access token","description":"The token is verified against the instance before anything is stored, and the URL is rejected if it resolves to a private address. Re-connecting an instance already linked replaces its token rather than adding a second connection, so rotating a token is the same call as connecting one.","responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"baseUrl":{"type":"string"},"gitlabUsername":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastUsedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","baseUrl","gitlabUsername","lastUsedAt","createdAt"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"gitlab:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-rate-limit":{"action":"provision","max":20,"windowMs":60000},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"baseUrl":{"type":"string","maxLength":512,"format":"uri"},"token":{"type":"string","minLength":8,"maxLength":1024}},"required":["baseUrl","token"]}}}}}},"/gitlab/connections/{id}":{"delete":{"operationId":"gitlab.disconnect","summary":"Disconnect a GitLab instance","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"gitlab:write","x-gheima-access":"admin","x-gheima-sensitive":true}},"/gitlab/repos":{"get":{"operationId":"gitlab.repos","summary":"List repositories reachable through each connection","description":"One entry per connection. A connection that cannot be listed carries `error` instead of failing the whole response.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"connectionId":{"type":"string","format":"uuid"},"baseUrl":{"type":"string"},"repos":{"type":"array","items":{"type":"object","properties":{"fullName":{"type":"string"},"cloneUrl":{"type":"string"},"defaultBranch":{"type":"string"},"private":{"type":"boolean"}},"required":["fullName","cloneUrl","defaultBranch","private"]}},"error":{"type":"string"}},"required":["connectionId","baseUrl","repos"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"gitlab:read","x-gheima-access":"read","x-gheima-sensitive":true}},"/links":{"get":{"operationId":"links.forResource","summary":"Services linked to a database or bucket","parameters":[{"name":"resourceType","in":"query","required":true,"schema":{"type":"string","enum":["DATABASE","BUCKET"]}},{"name":"resourceId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"linkId":{"type":"string","format":"uuid"},"serviceId":{"type":"string","format":"uuid"},"serviceName":{"type":"string"}},"required":["linkId","serviceId","serviceName"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"links:read","x-gheima-access":"read"}},"/log-drains":{"get":{"operationId":"logDrains.list","summary":"List log drains","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"url":{"type":"string"},"enabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"hasSecret":{"type":"boolean"}},"required":["id","name","url","enabled","createdAt","hasSecret"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"log-drains:read","x-gheima-access":"read","x-gheima-sensitive":true},"post":{"operationId":"logDrains.create","summary":"Create a log drain","description":"Logs are shipped to the URL as they are produced. Deliveries are signed when a secret is supplied, and always fetched through the SSRF guard.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"log-drains:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"url":{"type":"string","format":"uri"},"secret":{"type":"string","maxLength":200}},"required":["name","url"]}}}}}},"/log-drains/{id}":{"patch":{"operationId":"logDrains.update","summary":"Enable or disable a log drain","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"log-drains:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]}}}}},"delete":{"operationId":"logDrains.delete","summary":"Delete a log drain","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"log-drains:write","x-gheima-access":"admin","x-gheima-sensitive":true}},"/log-drains/{id}/test":{"post":{"operationId":"logDrains.test","summary":"Send a test payload to a log drain","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"log-drains:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true}},"/previews":{"get":{"operationId":"previews.list","summary":"List pull-request previews","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"prNumber":{"anyOf":[{"type":"integer"},{"type":"null"}]},"url":{"type":"string"},"status":{"type":"string"},"sourceName":{"anyOf":[{"type":"string"},{"type":"null"}]},"expiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","prNumber","url","status","sourceName","expiresAt","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"previews:read","x-gheima-access":"read"}},"/previews/{id}":{"delete":{"operationId":"previews.delete","summary":"Tear down a preview","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"previews:write","x-gheima-access":"write"}},"/previews/sources":{"get":{"operationId":"previews.sources","summary":"Services that can have previews created for them","description":"A service qualifies once it has a repository connected.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"repoBranch":{"anyOf":[{"type":"string"},{"type":"null"}]},"autoCreatePreviews":{"type":"boolean"}},"required":["id","name","repoBranch","autoCreatePreviews"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"previews:read","x-gheima-access":"read"}},"/projects":{"get":{"operationId":"projects.list","summary":"List projects","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"serviceCount":{"type":"integer"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","slug","description","serviceCount","updatedAt"]}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"projects:read","x-gheima-access":"read"},"post":{"operationId":"projects.create","summary":"Create a project","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"isPortfolio":{"type":"boolean"},"regionCode":{"type":"string"}},"required":["id","slug","name","isPortfolio","regionCode"]}},"required":["project"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"projects:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":500},"regionCode":{"type":"string","maxLength":32}},"required":["name"]}}}}}},"/projects/{id}":{"get":{"operationId":"projects.get","summary":"Get a project with its services","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"createdBy":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"name":{"type":"string"},"slug":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"isPortfolio":{"type":"boolean"},"regionCode":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"deletedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"services":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"subdomain":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","slug","type","status","subdomain"]}}},"required":["id","accountId","createdBy","name","slug","description","isPortfolio","regionCode","createdAt","updatedAt","deletedAt","services"]}},"required":["project"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"projects:read","x-gheima-access":"read"},"patch":{"operationId":"projects.update","summary":"Update a project’s name, description or portfolio flag","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"projects:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"isPortfolio":{"type":"boolean"}}}}}}},"delete":{"operationId":"projects.delete","summary":"Delete an empty project","description":"The project’s services must be deleted or moved first.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"projects:write","x-gheima-access":"admin"}},"/queues":{"get":{"operationId":"queues.list","summary":"List managed queues","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"keyPrefix":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","status","keyPrefix"]}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"queues:read","x-gheima-access":"read"},"post":{"operationId":"queues.create","summary":"Create a managed queue","description":"Provisioned in the background; poll the queue until its status is RUNNING.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"queueInstanceId":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["queueInstanceId","name"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"queues:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60}},"required":["name"]}}}}}},"/queues/{id}":{"get":{"operationId":"queues.get","summary":"Get a managed queue","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"host":{"anyOf":[{"type":"string"},{"type":"null"}]},"keyPrefix":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","status","host","keyPrefix"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"queues:read","x-gheima-access":"read"},"delete":{"operationId":"queues.delete","summary":"Deprovision a managed queue","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"queues:write","x-gheima-access":"admin"}},"/queues/{id}/reveal":{"post":{"operationId":"queues.reveal","summary":"Reveal a queue’s connection credentials","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"connectionString":{"type":"string"},"host":{"type":"string"},"port":{"type":"integer"},"username":{"type":"string"},"password":{"type":"string"},"keyPrefix":{"type":"string"}},"required":["connectionString","host","port","username","password","keyPrefix"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"queues:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-rate-limit":{"action":"reveal","max":30,"windowMs":60000}}},"/queues/{id}/rotate-password":{"post":{"operationId":"queues.rotatePassword","summary":"Rotate a queue’s password","description":"Queued in the background. The old password stops working once it lands.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"queues:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true}},"/regions":{"get":{"operationId":"regions.list","summary":"Regions this account may place workloads in","description":"Filtered by the account’s plan and residency entitlement, so what comes back is what this account can actually choose, not the whole fleet.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"label":{"type":"string"},"country":{"type":"string"},"dataResidency":{"type":"boolean"},"status":{"type":"string"},"isDefault":{"type":"boolean"},"appsDomain":{"type":"string"},"ingressIpv4":{"anyOf":[{"type":"string"},{"type":"null"}]},"supportsScaleToZero":{"type":"boolean"},"supportedDbEngines":{"type":"array","items":{"type":"string"}}},"required":["code","label","country","dataResidency","status","isDefault","appsDomain","ingressIpv4","supportsScaleToZero","supportedDbEngines"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"regions:read","x-gheima-access":"read"}},"/search/instances":{"get":{"operationId":"search.list","summary":"List managed search instances","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"indexPrefix":{"type":"string"}},"required":["id","name","status","indexPrefix"]}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"search:read","x-gheima-access":"read"},"post":{"operationId":"search.create","summary":"Create a managed search instance","description":"Provisioned in the background; poll until its status is RUNNING.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"searchInstanceId":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["searchInstanceId","name"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"search:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60}},"required":["name"]}}}}}},"/search/instances/{id}":{"get":{"operationId":"search.get","summary":"Get a managed search instance","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"host":{"anyOf":[{"type":"string"},{"type":"null"}]},"indexPrefix":{"type":"string"}},"required":["id","name","status","host","indexPrefix"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"search:read","x-gheima-access":"read"},"delete":{"operationId":"search.delete","summary":"Deprovision a managed search instance","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"search:write","x-gheima-access":"admin"}},"/search/instances/{id}/reveal":{"post":{"operationId":"search.reveal","summary":"Reveal a search instance’s API key","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string"},"apiKey":{"type":"string"},"indexPrefix":{"type":"string"}},"required":["host","apiKey","indexPrefix"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"search:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-rate-limit":{"action":"reveal","max":30,"windowMs":60000}}},"/search/instances/{id}/rotate-key":{"post":{"operationId":"search.rotateKey","summary":"Rotate a search instance’s API key","description":"Queued in the background. The old key stops working once it lands.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"search:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true}},"/services":{"get":{"operationId":"services.list","summary":"List services","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string","enum":["WEB","WORKER","STATIC"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"region":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"branch":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","slug","type","status","region","url","branch"]}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"},"post":{"operationId":"services.create","summary":"Create a service","description":"Omit `projectId` to leave the service ungrouped.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"service":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"subdomain":{"type":"string"},"regionCode":{"type":"string"},"appsDomain":{"type":"string"}},"required":["id","slug","subdomain","regionCode","appsDomain"]}},"required":["service"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":60},"type":{"type":"string","enum":["WEB","WORKER","STATIC"]},"repoUrl":{"type":"string","format":"uri"},"repoBranch":{"type":"string","maxLength":255},"port":{"type":"integer","minimum":1,"maximum":65535},"staticOutputDir":{"type":"string","maxLength":120},"regionCode":{"type":"string","maxLength":32}},"required":["name"]}}}}}},"/services/{id}":{"get":{"operationId":"services.get","summary":"Get a service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"service":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"projectId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"subdomain":{"anyOf":[{"type":"string"},{"type":"null"}]},"regionCode":{"type":"string"},"dataResidency":{"type":"boolean"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"repoUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"repoBranch":{"anyOf":[{"type":"string"},{"type":"null"}]},"autoDeploy":{"type":"boolean"},"waitForChecks":{"type":"boolean"},"buildCommand":{"anyOf":[{"type":"string"},{"type":"null"}]},"startCommand":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseCommand":{"anyOf":[{"type":"string"},{"type":"null"}]},"port":{"type":"integer"},"replicas":{"type":"integer"},"memoryMb":{"type":"integer"},"cpuLimit":{"type":"number"},"autoscaleEnabled":{"type":"boolean"},"autoscaleMin":{"type":"integer"},"autoscaleMax":{"type":"integer"},"autoscaleCpuTarget":{"type":"integer"},"sleepAfterMin":{"anyOf":[{"type":"integer"},{"type":"null"}]},"healthCheckPath":{"anyOf":[{"type":"string"},{"type":"null"}]},"dockerImage":{"anyOf":[{"type":"string"},{"type":"null"}]},"staticOutputDir":{"anyOf":[{"type":"string"},{"type":"null"}]},"staticConfig":{},"rootDirectory":{"anyOf":[{"type":"string"},{"type":"null"}]},"dockerfilePath":{"anyOf":[{"type":"string"},{"type":"null"}]},"buildEnvKeys":{"type":"array","items":{"type":"string"}},"rolloutStrategy":{"type":"string"}},"required":["id","projectId","name","slug","type","status","subdomain","regionCode","dataResidency","url","repoUrl","repoBranch","autoDeploy","waitForChecks","buildCommand","startCommand","releaseCommand","port","replicas","memoryMb","cpuLimit","autoscaleEnabled","autoscaleMin","autoscaleMax","autoscaleCpuTarget","sleepAfterMin","healthCheckPath","dockerImage","staticOutputDir","staticConfig","rootDirectory","dockerfilePath","buildEnvKeys","rolloutStrategy"]}},"required":["service"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"},"patch":{"operationId":"services.update","summary":"Update a service’s settings","description":"An empty `healthCheckPath` disables the container healthcheck. That is the only way to deploy an image with no shell or HTTP client to probe with (scratch, distroless). `buildEnvKeys` replaces the whole list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"repoUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"repoBranch":{"type":"string","maxLength":255},"autoDeploy":{"type":"boolean"},"waitForChecks":{"type":"boolean"},"buildCommand":{"anyOf":[{"type":"string"},{"type":"null"}]},"startCommand":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseCommand":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]},"port":{"type":"integer","minimum":1,"maximum":65535},"replicas":{"type":"integer","minimum":1,"maximum":10},"memoryMb":{"type":"integer","minimum":128,"maximum":8192},"cpuLimit":{"type":"number","minimum":0.1,"maximum":8},"healthCheckPath":{"anyOf":[{"type":"string","const":""},{"type":"string","pattern":"^\\/.*"}]},"staticOutputDir":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"rootDirectory":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"dockerfilePath":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"buildEnvKeys":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"rolloutStrategy":{"type":"string","enum":["ROLLING","BLUE_GREEN"]}}}}}}},"delete":{"operationId":"services.delete","summary":"Delete a service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"admin"}},"/services/{id}/analytics":{"get":{"operationId":"analytics.overview","summary":"Web analytics for a service","description":"First-party page views and visitors, with no third-party script and no cookies.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"range","in":"query","schema":{"default":"7d","type":"string","enum":["24h","7d","30d"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"totals":{"type":"object","properties":{"pageviews":{"type":"number"},"visitors":{"type":"number"}},"required":["pageviews","visitors"]},"bucket":{"type":"string","enum":["hour","day"]},"series":{"type":"array","items":{"type":"object","properties":{"t":{"type":"number"},"pageviews":{"type":"number"},"visitors":{"type":"number"}},"required":["t","pageviews","visitors"]}},"topPages":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"pageviews":{"type":"number"},"visitors":{"type":"number"}},"required":["key","pageviews","visitors"]}},"topReferrers":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"pageviews":{"type":"number"},"visitors":{"type":"number"}},"required":["key","pageviews","visitors"]}},"countries":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"pageviews":{"type":"number"},"visitors":{"type":"number"}},"required":["key","pageviews","visitors"]}}},"required":["totals","bucket","series","topPages","topReferrers","countries"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"}},"/services/{id}/build-env":{"get":{"operationId":"services.buildEnv","summary":"List the variables exposed at build time","description":"Runtime variables are not visible to a build unless they are opted in here. `suggested` lists resolvable names a build plausibly needs but has not opted into. It is advisory only: nothing reaches a build until it is added to `keys`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"string"}},"serviceKeys":{"type":"array","items":{"type":"string"}},"suggested":{"type":"array","items":{"type":"string"}}},"required":["keys","serviceKeys","suggested"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"},"put":{"operationId":"services.setBuildEnv","summary":"Set which variables are exposed at build time","description":"Replaces the list. At most 100 names.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}},"required":["keys"]}}}}}},"/services/{id}/cancel":{"post":{"operationId":"services.cancel","summary":"Cancel an in-flight deployment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"deploymentId":{"type":"string","format":"uuid"}},"required":["deploymentId"]}}}}}},"/services/{id}/checks-access":{"get":{"operationId":"services.checksAccess","summary":"Whether the Git app can read this repo’s commit checks","description":"Push-to-deploy can wait for CI only when the installed app may read checks. When this reports no access, a gated deploy will not wait.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"access":{"type":"string","enum":["granted","missing","no_installation","unknown"]}},"required":["access"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"}},"/services/{id}/deploy":{"post":{"operationId":"services.deploy","summary":"Trigger a deployment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"deploymentId":{"type":"string","format":"uuid"}},"required":["deploymentId"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"x-gheima-rate-limit":{"action":"deploy","max":20,"windowMs":60000},"x-gheima-emits":["DEPLOYMENT_CREATED"]}},"/services/{id}/deploy-hook":{"get":{"operationId":"services.deployHook","summary":"Whether a deploy hook is configured","description":"The URL itself is returned only once, when the hook is created. This says only whether one exists, and it is still writer-gated, because the existence of an unauthenticated deploy credential is not a read-only concern.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"configured":{"type":"boolean"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["configured","url"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"write"},"post":{"operationId":"services.createDeployHook","summary":"Create or rotate the deploy hook","description":"Returns the hook URL ONCE. Anyone holding it can trigger a deploy without authenticating, so store it like a credential. Creating again rotates it, invalidating the previous URL.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"admin"},"delete":{"operationId":"services.revokeDeployHook","summary":"Revoke the deploy hook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"admin"}},"/services/{id}/deployments":{"get":{"operationId":"services.deployments","summary":"List recent deployments","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"commitSha":{"anyOf":[{"type":"string"},{"type":"null"}]},"commitMessage":{"anyOf":[{"type":"string"},{"type":"null"}]},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"finishedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"insight":{"anyOf":[{"type":"object","properties":{"summary":{"type":"string"},"cause":{"type":"string"},"fix":{"type":"string"},"category":{"type":"string"},"confidence":{"type":"number"},"source":{"type":"string"}},"required":["summary","cause","fix","category","confidence","source"]},{"type":"null"}]}},"required":["id","status","commitSha","commitMessage","errorMessage","createdAt","finishedAt","insight"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"}},"/services/{id}/domains":{"get":{"operationId":"domains.list","summary":"List a service’s custom domains","description":"Each domain carries the DNS records to create. The `a` record is present only for a region that publishes an ingress IP, because an apex domain cannot be a CNAME. It always points at that region’s own ingress.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"verified":{"type":"boolean"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"sslExpiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"dns":{"type":"object","properties":{"cname":{"type":"object","properties":{"host":{"type":"string"},"value":{"type":"string"}},"required":["host","value"]},"a":{"type":"object","properties":{"host":{"type":"string"},"value":{"type":"string"}},"required":["host","value"]},"txt":{"type":"object","properties":{"host":{"type":"string"},"value":{"type":"string"}},"required":["host","value"]}},"required":["cname","txt"]}},"required":["id","domain","verified","verifiedAt","sslExpiresAt","dns"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"},"post":{"operationId":"domains.add","summary":"Attach a custom domain to a service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","maxLength":253,"pattern":"^(?!-)[a-z0-9-]{1,63}(?<!-)(\\.(?!-)[a-z0-9-]{1,63}(?<!-))+$"}},"required":["domain"]}}}}}},"/services/{id}/env":{"get":{"operationId":"services.listEnv","summary":"List a service’s environment variable names","description":"Values are masked. Use `POST /services/{id}/reveal` to read them, except those with `secret: true`, which are write-only.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"masked":{"type":"string"},"build":{"type":"boolean"},"secret":{"type":"boolean"}},"required":["key","masked","build","secret"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"},"put":{"operationId":"services.setEnv","summary":"Create or update one environment variable","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":200},"value":{"type":"string","maxLength":32768},"secret":{"type":"boolean","const":true}},"required":["key","value"]}}}}}},"/services/{id}/env-groups":{"get":{"operationId":"envGroups.forService","summary":"List the env groups attached to a service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"groupId":{"type":"string","format":"uuid"},"name":{"type":"string"},"variableCount":{"type":"integer"}},"required":["groupId","name","variableCount"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"}},"/services/{id}/env-history":{"get":{"operationId":"services.envHistory","summary":"List a service’s environment variable history","description":"Newest first, the last 50 changes: which variable NAMES each one added, changed or removed, who made it and when. Values are never returned.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"action":{"type":"string"},"changedKeys":{"type":"array","items":{"type":"string"}},"restoredFromId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"actor":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","email"]},{"type":"null"}]},"actorHidden":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","action","changedKeys","restoredFromId","actor","actorHidden","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"}},"/services/{id}/env-history/{revisionId}/rollback":{"post":{"operationId":"services.rollbackEnv","summary":"Restore a service’s environment variables to a saved revision","description":"Restores the variables and build-time opt-ins as they were after that revision, as a new revision (so it can itself be undone). Takes effect on the next deploy. Values are restored server-side and never returned.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"revisionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"changedKeys":{"type":"array","items":{"type":"string"}}},"required":["ok","changedKeys"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write"}},"/services/{id}/env/{envKey}":{"patch":{"operationId":"services.updateEnv","summary":"Rename an environment variable, change its value, or both","description":"Renaming through the collection would be a create plus a delete with a window in between, so it is one call here. Provide `key`, `value`, or both. The path carries the CURRENT name; a `key` in the body is the new one.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"envKey","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":200},"value":{"type":"string","maxLength":32768},"secret":{"type":"boolean","const":true}}}}}}},"delete":{"operationId":"services.removeEnv","summary":"Remove an environment variable","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"envKey","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write"}},"/services/{id}/env/import":{"post":{"operationId":"services.importEnv","summary":"Import .env text into a service","description":"Merges by default; `replace: true` discards what was there, except variables marked secret, which cannot be read back to resubmit and are kept (remove one explicitly). `secret: true` marks every imported variable secret. `invalidLines` gives the 1-based line numbers that could not be parsed. Those lines are skipped, not fatal.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"imported":{"type":"integer"},"total":{"type":"integer"},"invalidLines":{"type":"array","items":{"type":"integer"}}},"required":["imported","total","invalidLines"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"dotenv":{"type":"string","maxLength":200000},"replace":{"default":false,"type":"boolean"},"secret":{"type":"boolean","const":true}},"required":["dotenv"]}}}}}},"/services/{id}/links":{"get":{"operationId":"services.links","summary":"List linked resources","description":"A resource deleted out from under a link shows as `(deleted)`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"linkId":{"type":"string","format":"uuid"},"resourceType":{"type":"string"},"resourceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"envKeys":{"type":"array","items":{"type":"string"}}},"required":["linkId","resourceType","resourceId","name","envKeys"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"},"post":{"operationId":"services.createLink","summary":"Link a database or bucket to a service","description":"The linked resource contributes `envKeys` to the service at deploy time.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"linkId":{"type":"string","format":"uuid"},"envKeys":{"type":"array","items":{"type":"string"}}},"required":["linkId","envKeys"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"resourceType":{"type":"string","enum":["DATABASE","BUCKET"]},"resourceId":{"type":"string","format":"uuid"}},"required":["resourceType","resourceId"]}}}}}},"/services/{id}/links/{linkId}":{"delete":{"operationId":"services.removeLink","summary":"Unlink a resource","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"linkId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write"}},"/services/{id}/logs":{"get":{"operationId":"services.logs","summary":"Service logs (snapshot or SSE stream when follow=true)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string","enum":["runtime","build"]}},{"name":"follow","in":"query","schema":{"type":"boolean"}},{"name":"search","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Log snapshot (application/json) or SSE stream (text/event-stream)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LogEntry"}}}}},"text/event-stream":{"schema":{"type":"string"}}}}}}},"/services/{id}/metrics":{"get":{"operationId":"services.metrics","summary":"CPU, memory and network time series","description":"`configured: false` with empty series means this deployment has no metrics backend, not that the service is idle.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"minutes","in":"query","schema":{"default":30,"type":"integer","minimum":5,"maximum":360}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"metrics":{"type":"object","properties":{"configured":{"type":"boolean"},"cpu":{"type":"array","items":{"type":"object","properties":{"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"]}},"memory":{"type":"array","items":{"type":"object","properties":{"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"]}},"netRx":{"type":"array","items":{"type":"object","properties":{"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"]}},"netTx":{"type":"array","items":{"type":"object","properties":{"t":{"type":"number"},"v":{"type":"number"}},"required":["t","v"]}}},"required":["configured","cpu","memory","netRx","netTx"]}},"required":["metrics"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"}},"/services/{id}/move":{"post":{"operationId":"services.move","summary":"Move a service into a project, or ungroup it","description":"Pass `projectId: null` to ungroup. A preview service cannot be moved, and the target project must be in the same region.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"projectId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"slug":{"type":"string"}},"required":["ok","projectId","slug"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]}},"required":["projectId"]}}}}}},"/services/{id}/pause":{"post":{"operationId":"services.pause","summary":"Pause a service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true}},"/services/{id}/previews/toggle":{"post":{"operationId":"services.togglePreviews","summary":"Turn automatic pull-request previews on or off","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]}}}}}},"/services/{id}/restart":{"post":{"operationId":"services.restart","summary":"Restart a service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true}},"/services/{id}/resume":{"post":{"operationId":"services.resume","summary":"Resume a paused service","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true}},"/services/{id}/reveal":{"post":{"operationId":"services.revealEnv","summary":"Reveal a service’s environment variables in plaintext","description":"The plain list at `GET /services/{id}/env` returns names only. This returns values, which routinely hold credentials, so it needs ADMIN, is rate limited, is recorded in the audit log, and a coarse `write` scope cannot reach it. Variables marked `secret` are never returned, to anyone.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}},"required":["key","value"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-rate-limit":{"action":"reveal","max":30,"windowMs":60000}}},"/services/{id}/rollback":{"post":{"operationId":"services.rollback","summary":"Roll back to an earlier deployment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"deploymentId":{"type":"string","format":"uuid"}},"required":["deploymentId"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"x-gheima-emits":["DEPLOYMENT_CREATED"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"deploymentId":{"type":"string","format":"uuid"}},"required":["deploymentId"]}}}}}},"/services/{id}/scale":{"post":{"operationId":"services.scale","summary":"Configure autoscaling","description":"`sleepAfterMin: 0` disables scale-to-zero. A service with a verified custom domain cannot scale to zero in every region, because the wake path has to be able to reach it.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"min":{"type":"integer","minimum":1,"maximum":10},"max":{"type":"integer","minimum":1,"maximum":10},"cpuTarget":{"type":"integer","minimum":10,"maximum":95},"sleepAfterMin":{"type":"integer","minimum":0,"maximum":1440}},"required":["enabled","min","max","cpuTarget"]}}}}}},"/services/{id}/static-config":{"put":{"operationId":"services.staticConfig","summary":"Set redirects, rewrites and headers for a static site","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"redirects":{"default":[],"maxItems":50,"type":"array","items":{"type":"object","properties":{"source":{"type":"string","minLength":1,"maxLength":200},"destination":{"type":"string","minLength":1,"maxLength":500},"permanent":{"type":"boolean"}},"required":["source","destination"]}},"rewrites":{"default":[],"maxItems":50,"type":"array","items":{"type":"object","properties":{"source":{"type":"string","minLength":1,"maxLength":200},"destination":{"type":"string","minLength":1,"maxLength":500}},"required":["source","destination"]}},"headers":{"default":[],"maxItems":50,"type":"array","items":{"type":"object","properties":{"source":{"type":"string","minLength":1,"maxLength":200},"headers":{"maxItems":20,"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":100},"value":{"type":"string","maxLength":500}},"required":["key","value"]}}},"required":["source","headers"]}}}}}}}}},"/services/{id}/volumes":{"get":{"operationId":"services.volumes","summary":"List persistent volumes","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"mountPath":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","mountPath","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:read","x-gheima-access":"read"},"post":{"operationId":"services.addVolume","summary":"Attach a persistent volume","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"mountPath":{"type":"string"}},"required":["id","mountPath"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"default":"","type":"string","maxLength":60},"mountPath":{"type":"string","minLength":2,"maxLength":512}},"required":["mountPath"]}}}}}},"/services/{id}/volumes/{volumeId}":{"delete":{"operationId":"services.removeVolume","summary":"Detach a persistent volume","description":"Takes effect on the next deploy. A detached volume cannot be reattached, and its data is permanently deleted 7 days after you detach it. If the service has not been redeployed by then, deletion waits until it has.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"volumeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"services:write","x-gheima-access":"write"}},"/sso/connections":{"get":{"operationId":"sso.list","summary":"List SSO connections","description":"The client secret is stored encrypted and is never returned.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"emailDomain":{"type":"string"},"issuer":{"type":"string"},"clientId":{"type":"string"},"defaultRole":{"type":"string"},"status":{"type":"string"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"lastLoginAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"record":{"type":"object","properties":{"type":{"type":"string","const":"TXT"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"]},"loginUrl":{"type":"string"}},"required":["id","emailDomain","issuer","clientId","defaultRole","status","verifiedAt","lastLoginAt","createdAt","record","loginUrl"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"sso:read","x-gheima-access":"read"},"post":{"operationId":"sso.create","summary":"Create an SSO connection","description":"The issuer is discovered before anything is stored, so a wrong URL fails here rather than at a user’s first sign-in.","responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"emailDomain":{"type":"string"},"issuer":{"type":"string"},"clientId":{"type":"string"},"defaultRole":{"type":"string"},"status":{"type":"string"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"lastLoginAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"record":{"type":"object","properties":{"type":{"type":"string","const":"TXT"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"]},"loginUrl":{"type":"string"}},"required":["id","emailDomain","issuer","clientId","defaultRole","status","verifiedAt","lastLoginAt","createdAt","record","loginUrl"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"sso:write","x-gheima-access":"admin","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"emailDomain":{"type":"string","minLength":3,"maxLength":253},"issuer":{"type":"string","maxLength":512,"format":"uri"},"clientId":{"type":"string","minLength":1,"maxLength":512},"clientSecret":{"type":"string","minLength":1,"maxLength":1024}},"required":["emailDomain","issuer","clientId","clientSecret"]}}}}}},"/sso/connections/{id}":{"get":{"operationId":"sso.get","summary":"Get an SSO connection","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"emailDomain":{"type":"string"},"issuer":{"type":"string"},"clientId":{"type":"string"},"defaultRole":{"type":"string"},"status":{"type":"string"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"lastLoginAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"record":{"type":"object","properties":{"type":{"type":"string","const":"TXT"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"]},"loginUrl":{"type":"string"}},"required":["id","emailDomain","issuer","clientId","defaultRole","status","verifiedAt","lastLoginAt","createdAt","record","loginUrl"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"sso:read","x-gheima-access":"read"},"patch":{"operationId":"sso.setEnabled","summary":"Enable or disable an SSO connection","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"emailDomain":{"type":"string"},"issuer":{"type":"string"},"clientId":{"type":"string"},"defaultRole":{"type":"string"},"status":{"type":"string"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"lastLoginAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"record":{"type":"object","properties":{"type":{"type":"string","const":"TXT"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"]},"loginUrl":{"type":"string"}},"required":["id","emailDomain","issuer","clientId","defaultRole","status","verifiedAt","lastLoginAt","createdAt","record","loginUrl"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"sso:write","x-gheima-access":"admin","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]}}}}},"delete":{"operationId":"sso.delete","summary":"Delete an SSO connection","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"sso:write","x-gheima-access":"admin"}},"/sso/connections/{id}/verify":{"post":{"operationId":"sso.verify","summary":"Check an SSO connection’s TXT record","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"verified":{"type":"boolean"},"connection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"emailDomain":{"type":"string"},"issuer":{"type":"string"},"clientId":{"type":"string"},"defaultRole":{"type":"string"},"status":{"type":"string"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"lastLoginAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"record":{"type":"object","properties":{"type":{"type":"string","const":"TXT"},"name":{"type":"string"},"value":{"type":"string"}},"required":["type","name","value"]},"loginUrl":{"type":"string"}},"required":["id","emailDomain","issuer","clientId","defaultRole","status","verifiedAt","lastLoginAt","createdAt","record","loginUrl"]}},"required":["verified","connection"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"sso:write","x-gheima-access":"admin","x-gheima-idempotent":true}},"/storage/buckets":{"get":{"operationId":"storage.listBuckets","summary":"List buckets","parameters":[{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"public":{"type":"boolean"},"publicUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"objectCount":{"type":"integer"},"usedBytes":{"type":"string"}},"required":["id","name","status","public","publicUrl","objectCount","usedBytes"]}},"pagination":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hasMore","nextCursor"]}},"required":["data","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:read","x-gheima-access":"read"},"post":{"operationId":"storage.createBucket","summary":"Create a bucket","description":"Provisioned in the background; poll until its status is RUNNING.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"bucketId":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["bucketId","name"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"regionCode":{"type":"string","maxLength":32}},"required":["name"]}}}}}},"/storage/buckets/{id}":{"get":{"operationId":"storage.getBucket","summary":"Get a bucket","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"bucket":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"region":{"type":"string"},"status":{"type":"string"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}]},"accessKeyId":{"anyOf":[{"type":"string"},{"type":"null"}]},"quotaMb":{"type":"integer"},"usedBytes":{"type":"string"},"objectCount":{"type":"integer"},"public":{"type":"boolean"},"publicUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"cdnEnabled":{"type":"boolean"},"corsOrigins":{"type":"array","items":{"type":"string"}},"lifecycleExpireDays":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["id","name","region","status","endpoint","accessKeyId","quotaMb","usedBytes","objectCount","public","publicUrl","cdnEnabled","corsOrigins","lifecycleExpireDays"]}},"required":["bucket"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:read","x-gheima-access":"read"},"patch":{"operationId":"storage.setPublic","summary":"Publish a bucket, or make it private again","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"public":{"type":"boolean"}},"required":["ok","public"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"public":{"type":"boolean"}},"required":["public"]}}}}},"delete":{"operationId":"storage.deleteBucket","summary":"Deprovision a bucket","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"admin"}},"/storage/buckets/{id}/config":{"put":{"operationId":"storage.setConfig","summary":"Set CORS origins and object expiry","description":"`lifecycleExpireDays: 0` turns expiry off.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"corsOrigins":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":253}},"lifecycleExpireDays":{"type":"integer","minimum":0,"maximum":3650}}}}}}}},"/storage/buckets/{id}/objects":{"get":{"operationId":"storage.listObjects","summary":"List objects in a bucket","description":"Paged with `token`, not a cursor: the page token comes from the object store. A `search` value matches across the whole subtree rather than one level.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"prefix","in":"query","schema":{"default":"","type":"string","maxLength":1024}},{"name":"token","in":"query","schema":{"type":"string"}},{"name":"search","in":"query","schema":{"type":"string","maxLength":256}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"objects":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"size":{"type":"number"},"lastModified":{"type":"string"}},"required":["key","size","lastModified"]}},"prefixes":{"type":"array","items":{"type":"string"}},"nextToken":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["objects","prefixes","nextToken"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:read","x-gheima-access":"read"},"delete":{"operationId":"storage.deleteObject","summary":"Delete one object","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"key","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":1024}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"write"}},"/storage/buckets/{id}/objects/delete-folder":{"post":{"operationId":"storage.deleteFolder","summary":"Delete every object under a prefix","description":"The prefix must end with \"/\". Returns how many objects were removed. There is no undo: the objects are gone.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"deleted":{"type":"integer"}},"required":["ok","deleted"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prefix":{"type":"string","minLength":1,"maxLength":1024}},"required":["prefix"]}}}}}},"/storage/buckets/{id}/objects/presign":{"post":{"operationId":"storage.presign","summary":"Presign a URL to read or write one object","description":"The returned URL is a bearer credential for that one object until it expires. Anyone holding it can use it without authenticating.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"expiresIn":{"type":"integer"}},"required":["url","expiresIn"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":1024},"method":{"default":"GET","type":"string","enum":["GET","PUT"]},"expiresIn":{"default":3600,"type":"integer","minimum":1,"maximum":604800}},"required":["key"]}}}}}},"/storage/buckets/{id}/objects/rename":{"post":{"operationId":"storage.renameObject","summary":"Rename or move one object","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","minLength":1,"maxLength":1024},"to":{"type":"string","minLength":1,"maxLength":1024}},"required":["from","to"]}}}}}},"/storage/buckets/{id}/reveal":{"post":{"operationId":"storage.reveal","summary":"Reveal a bucket’s S3 credentials","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"bucket":{"type":"string"},"region":{"type":"string"},"endpoint":{"type":"string"},"accessKeyId":{"type":"string"},"secretAccessKey":{"type":"string"}},"required":["bucket","region","endpoint","accessKeyId","secretAccessKey"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-rate-limit":{"action":"reveal","max":30,"windowMs":60000}}},"/storage/buckets/{id}/rotate-keys":{"post":{"operationId":"storage.rotateKeys","summary":"Rotate a bucket’s S3 access keys","description":"Queued in the background. The old keys stop working once it lands.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"storage:write","x-gheima-access":"write","x-gheima-idempotent":true}},"/team/invites":{"get":{"operationId":"team.invites","summary":"List pending invites","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"role":{"type":"string","enum":["OWNER","ADMIN","MEMBER","VIEWER","INSTRUCTOR","STUDENT"]},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}},"required":["id","email","role","createdAt","expiresAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"team:read","x-gheima-access":"read","x-gheima-sensitive":true},"post":{"operationId":"team.invite","summary":"Invite a teammate by email","description":"Sends an accept link. Inviting an ADMIN requires the OWNER role. An API key is capped at ADMIN, so it cannot widen the admin set.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"role":{"type":"string","enum":["ADMIN","MEMBER","VIEWER"]}},"required":["id","email","role"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"team:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"x-gheima-rate-limit":{"action":"team-invite","max":30,"windowMs":3600000},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"role":{"default":"MEMBER","type":"string","enum":["ADMIN","MEMBER","VIEWER"]}},"required":["email"]}}}}}},"/team/invites/{inviteId}":{"delete":{"operationId":"team.revokeInvite","summary":"Revoke a pending invite","parameters":[{"name":"inviteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"team:write","x-gheima-access":"admin","x-gheima-sensitive":true}},"/team/members":{"get":{"operationId":"team.members","summary":"List team members","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"type":"string"},"image":{"anyOf":[{"type":"string"},{"type":"null"}]},"role":{"type":"string","enum":["OWNER","ADMIN","MEMBER","VIEWER","INSTRUCTOR","STUDENT"]},"joinedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"isSelf":{"type":"boolean"}},"required":["id","userId","name","email","image","role","joinedAt","isSelf"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"team:read","x-gheima-access":"read","x-gheima-sensitive":true}},"/team/members/{memberId}":{"patch":{"operationId":"team.updateRole","summary":"Change a member's role","description":"Granting ADMIN, and anything touching an OWNER, requires the OWNER role. The account must always keep at least one owner, and nobody may change their own role.","parameters":[{"name":"memberId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"team:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["OWNER","ADMIN","MEMBER","VIEWER"]}},"required":["role"]}}}}},"delete":{"operationId":"team.removeMember","summary":"Remove a member from the account","parameters":[{"name":"memberId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"team:write","x-gheima-access":"admin","x-gheima-sensitive":true}},"/templates":{"get":{"operationId":"templates.list","summary":"List the one-click template catalogue","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"image":{"type":"string"},"port":{"type":"integer"},"database":{"anyOf":[{"type":"string"},{"type":"null"}]},"hasVolume":{"type":"boolean"},"inputs":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"default":{"anyOf":[{"type":"string"},{"type":"null"}]},"required":{"type":"boolean"}},"required":["key","label","default","required"]}}},"required":["id","name","description","image","port","database","hasVolume","inputs"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"templates:read","x-gheima-access":"read"}},"/templates/deploy":{"post":{"operationId":"templates.deploy","summary":"Deploy a template","description":"Creates the service (and its database, if the template needs one) and starts the first deploy. Returns as soon as the work is queued. Omit `projectId` to leave the service ungrouped. A failure part-way removes the service again.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"202":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"serviceId":{"type":"string","format":"uuid"},"url":{"type":"string"}},"required":["serviceId","url"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"templates:write","x-gheima-access":"write","x-gheima-idempotent":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid"},"templateId":{"type":"string","minLength":1,"maxLength":60},"name":{"type":"string","minLength":1,"maxLength":60},"env":{"description":"Answers to the template's `inputs`, by env key.","type":"object","propertyNames":{"type":"string","maxLength":128},"additionalProperties":{"type":"string","maxLength":4096}}},"required":["templateId","name"]}}}}}},"/usage":{"get":{"operationId":"account.usage","summary":"This month’s usage, cost and plan limits","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"usage":{"type":"object","properties":{"plan":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"price":{"type":"number"},"limits":{"type":"object","properties":{"services":{"type":"number"},"memoryMbPerService":{"type":"number"},"cpuPerService":{"type":"number"},"databases":{"type":"number"},"customDomains":{"type":"number"},"teamMembers":{"type":"number"},"buildMinutesPerMonth":{"type":"number"},"bandwidthGbPerMonth":{"type":"number"},"objectStorageBuckets":{"type":"number"},"objectStorageGb":{"type":"number"},"dbStorageGb":{"type":"number"},"volumeStorageGb":{"type":"number"},"mysqlInstances":{"type":"number"},"mongoInstances":{"type":"number"},"cronJobs":{"type":"number"},"minCronIntervalMin":{"type":"number"},"previewEnvironments":{"type":"number"},"staticSites":{"type":"number"},"maxReplicasPerService":{"type":"number"},"backupRetentionMax":{"type":"number"},"envGroups":{"type":"number"},"searchInstances":{"type":"number"},"queueInstances":{"type":"number"}},"required":["services","memoryMbPerService","cpuPerService","databases","customDomains","teamMembers","buildMinutesPerMonth","bandwidthGbPerMonth","objectStorageBuckets","objectStorageGb","dbStorageGb","volumeStorageGb","mysqlInstances","mongoInstances","cronJobs","minCronIntervalMin","previewEnvironments","staticSites","maxReplicasPerService","backupRetentionMax","envGroups","searchInstances","queueInstances"]}},"required":["key","name","price","limits"]},"addOns":{"type":"object","properties":{"dataResidency":{"type":"boolean"},"dataResidencyTier":{"type":"string"},"dataResidencyIncluded":{"type":"object","properties":{"memoryMb":{"type":"integer"},"maxServices":{"type":"integer"},"egressGbPerMonth":{"type":"integer"},"priceMad":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["memoryMb","maxServices","egressGbPerMonth","priceMad"]}},"required":["dataResidency","dataResidencyTier","dataResidencyIncluded"]},"totals":{"type":"object","properties":{"cpuHours":{"type":"number"},"memoryGbHours":{"type":"number"},"bandwidthGb":{"type":"number"},"storageGb":{"type":"number"},"buildMinutes":{"type":"number"}},"required":["cpuHours","memoryGbHours","bandwidthGb","storageGb","buildMinutes"]},"costMad":{"type":"number"},"counts":{"type":"object","properties":{"services":{"type":"integer"},"databases":{"type":"integer"},"members":{"type":"integer"}},"required":["services","databases","members"]}},"required":["plan","addOns","totals","costMad","counts"]}},"required":["usage"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"usage:read","x-gheima-access":"read"}},"/usage/breakdown":{"get":{"operationId":"account.usageBreakdown","summary":"This month’s usage and cost per service","description":"Highest cost first. A deleted service still appears for what it used.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"period":{"type":"string","format":"date-time"},"resources":{"type":"array","items":{"type":"object","properties":{"serviceId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"name":{"type":"string"},"deleted":{"type":"boolean"},"totals":{"type":"object","properties":{"cpuHours":{"type":"number"},"memoryGbHours":{"type":"number"},"bandwidthGb":{"type":"number"},"storageGb":{"type":"number"},"buildMinutes":{"type":"number"}},"required":["cpuHours","memoryGbHours","bandwidthGb","storageGb","buildMinutes"]},"costMad":{"type":"number"}},"required":["serviceId","name","deleted","totals","costMad"]}},"totalMad":{"type":"number"}},"required":["period","resources","totalMad"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"usage:read","x-gheima-access":"read"}},"/webhooks":{"get":{"operationId":"webhooks.list","summary":"List webhooks","description":"The signing secret is never returned after creation.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"lastStatus":{"anyOf":[{"type":"integer"},{"type":"null"}]},"lastDeliveryAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","url","events","enabled","lastStatus","lastDeliveryAt","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"webhooks:read","x-gheima-access":"read","x-gheima-sensitive":true},"post":{"operationId":"webhooks.create","summary":"Create a webhook","description":"Returns the signing secret ONCE. Store it, because you cannot read it again. An explicit empty `events` subscribes to everything; the field is required so nothing ends up subscribed to everything by omission.","responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"lastStatus":{"anyOf":[{"type":"integer"},{"type":"null"}]},"lastDeliveryAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"secret":{"type":"string"}},"required":["id","url","events","enabled","lastStatus","lastDeliveryAt","createdAt","secret"]}},"required":["webhook"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"webhooks:write","x-gheima-access":"admin","x-gheima-sensitive":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"maxItems":30,"type":"array","items":{"type":"string","enum":["DEPLOYMENT_CREATED","SERVICE_CREATED","SERVICE_DELETED","DATABASE_CREATED","PING"]}}},"required":["url","events"]}}}}}},"/webhooks/{id}":{"get":{"operationId":"webhooks.get","summary":"Get a webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"lastStatus":{"anyOf":[{"type":"integer"},{"type":"null"}]},"lastDeliveryAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","url","events","enabled","lastStatus","lastDeliveryAt","createdAt"]}},"required":["webhook"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"webhooks:read","x-gheima-access":"read","x-gheima-sensitive":true},"patch":{"operationId":"webhooks.update","summary":"Update a webhook’s URL, events or enabled state","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"webhooks:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"maxItems":30,"type":"array","items":{"type":"string","enum":["DEPLOYMENT_CREATED","SERVICE_CREATED","SERVICE_DELETED","DATABASE_CREATED","PING"]}},"enabled":{"type":"boolean"}}}}}}},"delete":{"operationId":"webhooks.delete","summary":"Delete a webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"webhooks:write","x-gheima-access":"admin","x-gheima-sensitive":true}},"/webhooks/{id}/deliveries":{"get":{"operationId":"webhooks.deliveries","summary":"List recent delivery attempts for a webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"event":{"type":"string"},"success":{"type":"boolean"},"statusCode":{"anyOf":[{"type":"integer"},{"type":"null"}]},"error":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","event","success","statusCode","error","createdAt"]}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"webhooks:read","x-gheima-access":"read","x-gheima-sensitive":true}},"/webhooks/{id}/test":{"post":{"operationId":"webhooks.test","summary":"Send a test ping to a webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"webhooks:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"x-gheima-rate-limit":{"action":"webhook-test","max":10,"windowMs":60000}}},"/webhooks/deliveries/{deliveryId}/redeliver":{"post":{"operationId":"webhooks.redeliver","summary":"Re-send a past webhook delivery","description":"Sends the original payload again and records the new attempt.","parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"A caller-chosen key, unique per logical request. Resending the same request with the same key returns the first response instead of acting again, for 24 hours.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Validation"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-gheima-scope":"webhooks:write","x-gheima-access":"admin","x-gheima-sensitive":true,"x-gheima-idempotent":true,"x-gheima-rate-limit":{"action":"webhook-test","max":10,"windowMs":60000}}}}}