openapi: 3.1.0
info:
  title: Steada API
  version: 1.0.0
  description: Versioned customer API used by the Steada dashboard and customer integrations.
servers:
  - url: https://api.steada.dev/v1
security:
  - bearerAuth: []
paths:
  /auth/magic-links:
    post:
      security: []
      summary: Request a sign-in link
      responses:
        '201': {description: Request accepted}
  /auth/magic-links/verify:
    post:
      security: []
      summary: Verify a sign-in link and create a session
      responses:
        '200': {description: Session created}
  /memberships:
    get:
      summary: List accessible workspaces
      responses:
        '200': {description: Membership list}
  /workspaces/{workspace_id}:
    get:
      summary: Get workspace state
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '200': {description: Workspace summary}
  /workspaces/{workspace_id}/databases:
    post:
      summary: Provision a database
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '201': {description: Database and provisioning job created}
  /workspaces/{workspace_id}/databases/{database_id}:
    delete:
      summary: Decommission a database
      description: Interactive client-admin session required.
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {$ref: '#/components/parameters/DatabaseId'}]
      responses:
        '200': {description: Database decommissioned}
  /workspaces/{workspace_id}/databases/{database_id}/resize:
    post:
      summary: Resize a database
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {$ref: '#/components/parameters/DatabaseId'}]
      responses:
        '200': {description: Database resized}
  /workspaces/{workspace_id}/databases/{database_id}/durability-request:
    post:
      summary: Request durable storage
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {$ref: '#/components/parameters/DatabaseId'}]
      responses:
        '200': {description: Upgrade requested}
  /workspaces/{workspace_id}/databases/{database_id}/usage:
    get:
      summary: Read database usage
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {$ref: '#/components/parameters/DatabaseId'}, {name: range, in: query, schema: {type: string, enum: [1h, 24h, 7d, 30d]}}]
      responses:
        '200': {description: Usage series}
  /workspaces/{workspace_id}/database-credentials:
    post:
      summary: Create a database credential
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '201': {description: Credential secret returned once}
  /workspaces/{workspace_id}/database-credentials/{credential_id}/rotate:
    post:
      summary: Rotate a database credential
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {$ref: '#/components/parameters/CredentialId'}]
      responses:
        '200': {description: Replacement secret returned once}
  /workspaces/{workspace_id}/database-credentials/{credential_id}/status:
    post:
      summary: Change credential status
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {$ref: '#/components/parameters/CredentialId'}]
      responses:
        '200': {description: Credential status changed}
  /workspaces/{workspace_id}/alerts:
    post:
      summary: Create an alert rule
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '201': {description: Alert created}
  /workspaces/{workspace_id}/alerts/{alert_id}:
    delete:
      summary: Delete an alert rule
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {name: alert_id, in: path, required: true, schema: {type: string}}]
      responses:
        '200': {description: Alert deleted}
  /workspaces/{workspace_id}/alerts/{alert_id}/enabled:
    post:
      summary: Enable or disable an alert rule
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {name: alert_id, in: path, required: true, schema: {type: string}}]
      responses:
        '200': {description: Alert updated}
  /workspaces/{workspace_id}/support-requests:
    post:
      summary: Open a support request
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '201': {description: Request opened}
  /workspaces/{workspace_id}/api-keys:
    post:
      summary: Create a scoped API key
      description: Interactive client-admin session required. The secret is returned once.
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '201': {description: API key created}
  /workspaces/{workspace_id}/api-keys/{key_id}:
    delete:
      summary: Revoke an API key
      description: Interactive client-admin session required.
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {name: key_id, in: path, required: true, schema: {type: string}}]
      responses:
        '200': {description: API key revoked}
  /workspaces/{workspace_id}/api-keys/{key_id}/rotate:
    post:
      summary: Create an overlapping replacement API key
      description: The predecessor remains active until explicitly revoked. Interactive client-admin session required.
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}, {name: key_id, in: path, required: true, schema: {type: string}}]
      responses:
        '201': {description: Replacement secret returned once}
  /workspaces/{workspace_id}/exports/prometheus:
    get:
      summary: Export Prometheus metrics
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '200': {description: Prometheus text exposition}
  /workspaces/{workspace_id}/exports/usage.csv:
    get:
      summary: Export usage CSV
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '200': {description: CSV export}
  /workspaces/{workspace_id}/billing/summary:
    get:
      summary: Read subscription state
      description: Interactive client-admin session required.
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '200': {description: Billing summary}
  /workspaces/{workspace_id}/billing/checkout-session:
    post:
      summary: Create a Stripe Checkout session
      description: Interactive client-admin session required.
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '200': {description: Checkout URL}
  /workspaces/{workspace_id}/billing/portal-session:
    post:
      summary: Create a Stripe Billing Portal session
      description: Interactive client-admin session required.
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '200': {description: Portal URL}
  /workspaces/{workspace_id}/events:
    post:
      summary: Record an allowlisted activation event
      parameters: [{$ref: '#/components/parameters/WorkspaceId'}]
      responses:
        '202': {description: Event accepted}
components:
  securitySchemes:
    bearerAuth: {type: http, scheme: bearer}
  parameters:
    WorkspaceId: {name: workspace_id, in: path, required: true, schema: {type: string}}
    DatabaseId: {name: database_id, in: path, required: true, schema: {type: string}}
    CredentialId: {name: credential_id, in: path, required: true, schema: {type: string}}
