Created
December 24, 2025 09:39
-
-
Save mikaelvesavuori/89f226d17c8099767221a66b4bc2f486 to your computer and use it in GitHub Desktop.
Test schema for MolnOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| openapi: 3.1.0 | |
| info: | |
| title: MolnOS Core API | |
| version: 0.0.1 | |
| description: | | |
| MolnOS is a minimalist, ultra-portable microscaler that runs on almost any hardware. | |
| It provides a control plane for managing IAM (Identity and Access Management) and services | |
| such as serverless functions, static site hosting, object storage, and databases. | |
| ## Authentication | |
| MolnOS supports two authentication methods: | |
| 1. JWT Bearer Tokens - For user sessions | |
| - Obtain via magic link authentication flow | |
| - Include in requests: `Authorization: Bearer <jwt_token>` | |
| 2. Service Account API Keys - For machine-to-machine authentication | |
| - Create via `/identity/service-accounts` endpoint | |
| - Include in requests: `Authorization: Bearer sa.<id>.<key>` | |
| ## Authorization | |
| MolnOS uses Role-Based Access Control (RBAC) with fine-grained permissions. | |
| All authenticated endpoints check permissions before allowing access. | |
| contact: | |
| name: Mikael Vesavuori | |
| url: https://github.com/mikaelvesavuori/molnos-gateway | |
| license: | |
| name: MIT | |
| url: https://opensource.org/licenses/MIT | |
| servers: | |
| - url: http://localhost:3000 | |
| description: Local development server | |
| - url: https://api.molnos.example.com | |
| description: Production server (example) | |
| tags: | |
| - name: Health | |
| description: System health check endpoints | |
| - name: Authentication | |
| description: User authentication and session management | |
| - name: Identity | |
| description: User and service account management (IAM) | |
| - name: Management | |
| description: Service lifecycle and process management | |
| - name: Databases | |
| description: Key-value database operations (PikoDB) | |
| - name: Functions | |
| description: Serverless function deployment and execution (FaaS) | |
| - name: Storage | |
| description: Object storage with S3-like API | |
| - name: Sites | |
| description: Static site hosting and deployment | |
| - name: Observability | |
| description: Logging and event tracking | |
| security: | |
| - BearerAuth: [] | |
| - ServiceAccountAuth: [] | |
| paths: | |
| /health: | |
| get: | |
| tags: | |
| - Health | |
| summary: Health check | |
| description: Returns system health status | |
| operationId: healthCheck | |
| security: [] | |
| responses: | |
| '200': | |
| description: System is healthy | |
| content: | |
| text/plain: | |
| schema: | |
| type: string | |
| example: OK | |
| # Authentication Endpoints | |
| /auth/login: | |
| post: | |
| tags: | |
| - Authentication | |
| summary: Request magic link | |
| description: Initiates the sign-in flow by creating and sending a magic link to the user's email | |
| operationId: authLogin | |
| security: [] | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| description: User's email address | |
| example: user@example.com | |
| responses: | |
| '200': | |
| description: Magic link sent successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| message: | |
| type: string | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '404': | |
| description: User not found (when invite-only mode is enabled) | |
| /auth/verify: | |
| get: | |
| tags: | |
| - Authentication | |
| summary: Verify magic link | |
| description: Verifies the magic link token and returns JWT tokens. Used when clicking magic link from email or forwarded from a client application. | |
| operationId: authVerify | |
| security: [] | |
| parameters: | |
| - name: token | |
| in: query | |
| required: true | |
| schema: | |
| type: string | |
| description: Magic link token | |
| example: 3cfc02067d48ae260456d6d87e37f8df1159dc2bb633d6793d2e1b42756bd2f3 | |
| - name: email | |
| in: query | |
| required: true | |
| schema: | |
| type: string | |
| format: email | |
| description: User's email address | |
| example: user@example.com | |
| responses: | |
| '200': | |
| description: Token verified successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| accessToken: | |
| type: string | |
| description: JWT access token | |
| refreshToken: | |
| type: string | |
| description: Refresh token for obtaining new access tokens | |
| expiresIn: | |
| type: number | |
| description: Token expiry in seconds | |
| user: | |
| $ref: '#/components/schemas/Identity' | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| description: Invalid or expired token | |
| /auth/refresh: | |
| post: | |
| tags: | |
| - Authentication | |
| summary: Refresh access token | |
| description: Exchanges a refresh token for a new access token | |
| operationId: authRefresh | |
| security: [] | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - refreshToken | |
| properties: | |
| refreshToken: | |
| type: string | |
| description: The refresh token obtained from login/verify | |
| responses: | |
| '200': | |
| description: New access token issued | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| accessToken: | |
| type: string | |
| expiresIn: | |
| type: number | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| description: Invalid or expired refresh token | |
| /auth/dev-login: | |
| post: | |
| tags: | |
| - Authentication | |
| summary: Development login (dev mode only) | |
| description: Direct login without magic link for development purposes. Only available when devMode is enabled. | |
| operationId: authDevLogin | |
| security: [] | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| responses: | |
| '200': | |
| description: Login successful | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| user: | |
| $ref: '#/components/schemas/Identity' | |
| token: | |
| type: string | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| # Identity Endpoints | |
| /identity/whoami: | |
| get: | |
| tags: | |
| - Identity | |
| summary: Get current identity | |
| description: Returns details about the currently authenticated identity | |
| operationId: getWhoami | |
| responses: | |
| '200': | |
| description: Current identity details | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EnrichedIdentity' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /identity/identities: | |
| get: | |
| tags: | |
| - Identity | |
| summary: List all identities | |
| description: Returns all users and service accounts | |
| operationId: listIdentities | |
| responses: | |
| '200': | |
| description: List of all identities | |
| content: | |
| application/json: | |
| schema: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Identity' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /identity/users: | |
| get: | |
| tags: | |
| - Identity | |
| summary: List all users | |
| description: Returns all user identities | |
| operationId: listUsers | |
| responses: | |
| '200': | |
| description: List of users | |
| content: | |
| application/json: | |
| schema: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Identity' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| post: | |
| tags: | |
| - Identity | |
| summary: Create user | |
| description: Creates a new user identity | |
| operationId: createUser | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - name | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| name: | |
| type: string | |
| roles: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/RoleId' | |
| default: ['user'] | |
| active: | |
| type: boolean | |
| default: true | |
| responses: | |
| '200': | |
| description: User created successfully | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EnrichedIdentity' | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /identity/users/{userId}: | |
| get: | |
| tags: | |
| - Identity | |
| summary: Get user | |
| description: Returns a specific user by ID | |
| operationId: getUser | |
| parameters: | |
| - $ref: '#/components/parameters/UserId' | |
| responses: | |
| '200': | |
| description: User details | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EnrichedIdentity' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| patch: | |
| tags: | |
| - Identity | |
| summary: Update user | |
| description: Updates user properties (name, email, roles, metadata) | |
| operationId: updateUser | |
| parameters: | |
| - $ref: '#/components/parameters/UserId' | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| email: | |
| type: string | |
| format: email | |
| roles: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/RoleId' | |
| metadata: | |
| type: object | |
| additionalProperties: true | |
| responses: | |
| '200': | |
| description: User updated successfully | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EnrichedIdentity' | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| delete: | |
| tags: | |
| - Identity | |
| summary: Delete user | |
| description: Deletes a user identity | |
| operationId: deleteUser | |
| parameters: | |
| - $ref: '#/components/parameters/UserId' | |
| responses: | |
| '200': | |
| description: User deleted successfully | |
| content: | |
| text/plain: | |
| schema: | |
| type: string | |
| example: OK | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /identity/service-accounts: | |
| get: | |
| tags: | |
| - Identity | |
| summary: List service accounts | |
| description: Returns all service account identities (API keys excluded) | |
| operationId: listServiceAccounts | |
| responses: | |
| '200': | |
| description: List of service accounts | |
| content: | |
| application/json: | |
| schema: | |
| type: array | |
| items: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| name: | |
| type: string | |
| description: | |
| type: string | |
| roles: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/RoleId' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| post: | |
| tags: | |
| - Identity | |
| summary: Create service account | |
| description: Creates a new service account with API key | |
| operationId: createServiceAccount | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - name | |
| - description | |
| - roles | |
| properties: | |
| name: | |
| type: string | |
| description: Service account name | |
| description: | |
| type: string | |
| description: Purpose of this service account | |
| roles: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/RoleId' | |
| description: Roles to assign | |
| responses: | |
| '201': | |
| description: Service account created successfully | |
| content: | |
| application/json: | |
| schema: | |
| allOf: | |
| - $ref: '#/components/schemas/EnrichedIdentity' | |
| - type: object | |
| properties: | |
| apiKey: | |
| type: string | |
| description: API key (store securely, shown only once) | |
| example: sa.abc123.def456789 | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /identity/service-accounts/{serviceAccountId}: | |
| get: | |
| tags: | |
| - Identity | |
| summary: Get service account | |
| description: Returns a specific service account by ID | |
| operationId: getServiceAccount | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceAccountId' | |
| responses: | |
| '200': | |
| description: Service account details | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EnrichedIdentity' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| patch: | |
| tags: | |
| - Identity | |
| summary: Update service account | |
| description: Updates service account properties | |
| operationId: updateServiceAccount | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceAccountId' | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| description: | |
| type: string | |
| roles: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/RoleId' | |
| responses: | |
| '200': | |
| description: Service account updated successfully | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/EnrichedIdentity' | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| delete: | |
| tags: | |
| - Identity | |
| summary: Delete service account | |
| description: Deletes a service account and revokes its API key | |
| operationId: deleteServiceAccount | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceAccountId' | |
| responses: | |
| '200': | |
| description: Service account deleted successfully | |
| content: | |
| text/plain: | |
| schema: | |
| type: string | |
| example: OK | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| # ROLES ENDPOINTS | |
| /identity/roles: | |
| get: | |
| tags: | |
| - Identity | |
| summary: List all roles | |
| description: Returns all roles (both base and custom) | |
| operationId: listRoles | |
| responses: | |
| '200': | |
| description: List of roles | |
| content: | |
| application/json: | |
| schema: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Role' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| post: | |
| tags: | |
| - Identity | |
| summary: Create custom role | |
| description: Creates a new custom role with specified permissions | |
| operationId: createRole | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - roleId | |
| - name | |
| - description | |
| - permissions | |
| properties: | |
| roleId: | |
| type: string | |
| description: Unique identifier for the role | |
| example: data-analyst | |
| name: | |
| type: string | |
| description: Human-readable name for the role | |
| example: Data Analyst | |
| description: | |
| type: string | |
| description: Description of the role's purpose | |
| example: Role for data analysts with read-only database access | |
| permissions: | |
| type: array | |
| items: | |
| type: string | |
| description: Array of permission strings | |
| example: | |
| - databases.read | |
| - observability.read | |
| constraints: | |
| $ref: '#/components/schemas/Constraints' | |
| responses: | |
| '201': | |
| description: Role created successfully | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Role' | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '409': | |
| description: Role with this ID already exists | |
| /identity/roles/{roleId}: | |
| get: | |
| tags: | |
| - Identity | |
| summary: Get role | |
| description: Returns a specific role by ID | |
| operationId: getRole | |
| parameters: | |
| - name: roleId | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Role identifier | |
| example: administrator | |
| responses: | |
| '200': | |
| description: Role details | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Role' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| patch: | |
| tags: | |
| - Identity | |
| summary: Update role | |
| description: Updates role properties (name, description, permissions, or constraints) | |
| operationId: updateRole | |
| parameters: | |
| - name: roleId | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Role identifier | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| description: Updated role name | |
| description: | |
| type: string | |
| description: Updated role description | |
| permissions: | |
| type: array | |
| items: | |
| type: string | |
| description: Updated permissions array | |
| constraints: | |
| $ref: '#/components/schemas/Constraints' | |
| responses: | |
| '200': | |
| description: Role updated successfully | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Role' | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| delete: | |
| tags: | |
| - Identity | |
| summary: Delete role | |
| description: Deletes a custom role (base roles cannot be deleted) | |
| operationId: deleteRole | |
| parameters: | |
| - name: roleId | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Role identifier | |
| responses: | |
| '200': | |
| description: Role deleted successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| message: | |
| type: string | |
| example: Role deleted successfully | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '403': | |
| description: Cannot delete base roles | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| # Management Endpoints | |
| /management/services: | |
| get: | |
| tags: | |
| - Management | |
| summary: List all services | |
| description: Returns all registered services and their configurations | |
| operationId: listServices | |
| responses: | |
| '200': | |
| description: List of services | |
| content: | |
| application/json: | |
| schema: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/ServiceConfig' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /management/service: | |
| post: | |
| tags: | |
| - Management | |
| summary: Register service | |
| description: | | |
| Registers a new service with the control plane. Supports three registration modes: | |
| 1. Predefined Service - Register by name only: | |
| ```json | |
| { "name": "sites" } | |
| ``` | |
| Available predefined services: `storage`, `functions`, `sites`, `databases`, `observability` | |
| 2. Predefined Service with Overrides - Override specific settings: | |
| ```json | |
| { "name": "sites", "port": 4000 } | |
| ``` | |
| 3. Custom Service - Full configuration for custom services: | |
| ```json | |
| { "name": "custom-service", "path": "./custom.js", "port": 5000, "prefix": "/custom" } | |
| ``` | |
| operationId: registerService | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| oneOf: | |
| - $ref: '#/components/schemas/PredefinedServiceRegistration' | |
| - $ref: '#/components/schemas/ServiceConfig' | |
| examples: | |
| predefinedService: | |
| summary: Register predefined service | |
| value: | |
| name: sites | |
| predefinedWithOverride: | |
| summary: Predefined service with overrides | |
| value: | |
| name: sites | |
| port: 4000 | |
| customService: | |
| summary: Custom service | |
| value: | |
| name: my-custom-service | |
| path: ./custom.js | |
| port: 5000 | |
| prefix: /custom | |
| responses: | |
| '201': | |
| description: Service registered successfully | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /management/service/{serviceName}: | |
| get: | |
| tags: | |
| - Management | |
| summary: Get service | |
| description: Returns service configuration and runtime status | |
| operationId: getService | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceName' | |
| responses: | |
| '200': | |
| description: Service details | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ServiceConfig' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| put: | |
| tags: | |
| - Management | |
| summary: Update service | |
| description: Updates service configuration | |
| operationId: updateService | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceName' | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/ServiceConfig' | |
| responses: | |
| '200': | |
| description: Service updated successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| delete: | |
| tags: | |
| - Management | |
| summary: Remove service | |
| description: Stops and unregisters a service | |
| operationId: removeService | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceName' | |
| responses: | |
| '200': | |
| description: Service removed successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| serviceName: | |
| type: string | |
| removed: | |
| type: boolean | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /management/service/{serviceName}/start: | |
| get: | |
| tags: | |
| - Management | |
| summary: Start service | |
| description: Starts a registered service | |
| operationId: startService | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceName' | |
| responses: | |
| '200': | |
| description: Service started | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| serviceName: | |
| type: string | |
| isStarted: | |
| type: boolean | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /management/service/{serviceName}/stop: | |
| get: | |
| tags: | |
| - Management | |
| summary: Stop service | |
| description: Stops a running service | |
| operationId: stopService | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceName' | |
| responses: | |
| '200': | |
| description: Service stopped | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| serviceName: | |
| type: string | |
| stopped: | |
| type: boolean | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /management/service/{serviceName}/restart: | |
| get: | |
| tags: | |
| - Management | |
| summary: Restart service | |
| description: Restarts a service (stop then start) | |
| operationId: restartService | |
| parameters: | |
| - $ref: '#/components/parameters/ServiceName' | |
| responses: | |
| '200': | |
| description: Service restarted | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| serviceName: | |
| type: string | |
| removed: | |
| type: boolean | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| # Databases Endpoints (Proxied) | |
| /databases/table: | |
| get: | |
| tags: | |
| - Databases | |
| summary: Get table size | |
| description: Returns the number of items in a table | |
| operationId: getTableSize | |
| parameters: | |
| - name: tableName | |
| in: query | |
| required: true | |
| schema: | |
| type: string | |
| description: Name of the table | |
| responses: | |
| '200': | |
| description: Table size | |
| content: | |
| application/json: | |
| schema: | |
| type: number | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /databases/get: | |
| post: | |
| tags: | |
| - Databases | |
| summary: Get value | |
| description: Retrieves a value from a table by key | |
| operationId: getDatabaseValue | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - tableName | |
| - key | |
| properties: | |
| tableName: | |
| type: string | |
| key: | |
| type: string | |
| responses: | |
| '200': | |
| description: Value retrieved successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: true | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /databases/write: | |
| post: | |
| tags: | |
| - Databases | |
| summary: Write value | |
| description: Writes a value to a table | |
| operationId: writeDatabaseValue | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - tableName | |
| - key | |
| - value | |
| properties: | |
| tableName: | |
| type: string | |
| key: | |
| type: string | |
| value: | |
| type: object | |
| additionalProperties: true | |
| expiration: | |
| type: number | |
| description: TTL in seconds | |
| dictionaryName: | |
| type: string | |
| description: Optional dictionary grouping | |
| responses: | |
| '200': | |
| description: Value written successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /databases/delete: | |
| delete: | |
| tags: | |
| - Databases | |
| summary: Delete value | |
| description: Deletes a value from a table | |
| operationId: deleteDatabaseValue | |
| parameters: | |
| - name: tableName | |
| in: query | |
| required: true | |
| schema: | |
| type: string | |
| - name: key | |
| in: query | |
| required: true | |
| schema: | |
| type: string | |
| responses: | |
| '200': | |
| description: Value deleted successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /databases/tables: | |
| get: | |
| tags: | |
| - Databases | |
| summary: List tables | |
| description: Returns all database tables | |
| operationId: listTables | |
| responses: | |
| '200': | |
| description: List of tables | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| tables: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/DatabaseTable' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /databases/tables/{tableName}/items: | |
| get: | |
| tags: | |
| - Databases | |
| summary: List items in table | |
| description: Returns all items (key-value pairs) in a specific table | |
| operationId: listTableItems | |
| parameters: | |
| - name: tableName | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Name of the table | |
| responses: | |
| '200': | |
| description: List of items in the table | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| items: | |
| type: array | |
| items: | |
| type: object | |
| properties: | |
| key: | |
| type: string | |
| description: Item key | |
| value: | |
| type: object | |
| description: Item value (JSON object) | |
| additionalProperties: true | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /databases/tables/{tableName}: | |
| get: | |
| tags: | |
| - Databases | |
| summary: Get table details | |
| description: Returns detailed information about a specific table | |
| operationId: getTable | |
| parameters: | |
| - name: tableName | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Name of the table | |
| responses: | |
| '200': | |
| description: Table details | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/DatabaseTable' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| post: | |
| tags: | |
| - Databases | |
| summary: Create table | |
| description: Creates a new empty database table | |
| operationId: createTable | |
| parameters: | |
| - name: tableName | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Name of the table to create | |
| responses: | |
| '201': | |
| description: Table created successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| name: | |
| type: string | |
| message: | |
| type: string | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '409': | |
| description: Table already exists | |
| content: | |
| application/json: | |
| schema: | |
| type: string | |
| example: 'Table already exists' | |
| delete: | |
| tags: | |
| - Databases | |
| summary: Delete table | |
| description: Deletes an entire database table and all its data | |
| operationId: deleteTable | |
| parameters: | |
| - name: tableName | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Name of the table to delete | |
| responses: | |
| '200': | |
| description: Table deleted successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| name: | |
| type: string | |
| message: | |
| type: string | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| # Functions Endpoints (Proxied) | |
| /functions/list: | |
| get: | |
| tags: | |
| - Functions | |
| summary: List functions | |
| description: Returns all deployed functions | |
| operationId: listFunctions | |
| responses: | |
| '200': | |
| description: List of functions | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| count: | |
| type: number | |
| functions: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Function' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /functions/deploy: | |
| post: | |
| tags: | |
| - Functions | |
| summary: Deploy function | |
| description: | | |
| Deploys a new serverless function with optional HTTP method restrictions and service bindings. | |
| Function Code Format: | |
| Functions must be written as a complete async function that accepts `(request, context)` parameters: | |
| ```javascript | |
| async function handler(request, context) { | |
| // Access request data | |
| const body = request.body; | |
| const headers = request.headers; | |
| const query = request.query; | |
| // Access context | |
| const functionId = context.functionId; | |
| const functionName = context.functionName; | |
| // Access service bindings (if configured) | |
| const databases = context.bindings.databases; | |
| const user = await databases.get('users-table', 'user123'); | |
| // Return response | |
| return { | |
| statusCode: 200, | |
| body: { message: 'Hello World', user } | |
| }; | |
| } | |
| ``` | |
| The `request` parameter contains: `method`, `path`, `subpath`, `query`, `headers`, `body` | |
| The `context` parameter contains: `request`, `env`, `functionId`, `functionName`, `bindings` | |
| Service Bindings: | |
| Functions can declare bindings to other services (databases, storage, etc.) to securely access them | |
| with service account permissions. Each function gets its own service account with minimal, scoped permissions. | |
| Three granularity levels (inferred from structure): | |
| - Service-level: No `resource` specified - grants access to entire service | |
| - Resource-level: `resource` specified, no `targets` - grants access to all resources of that type | |
| - Action-level: `resource` + `actions` + `targets` - grants access to specific resources only | |
| Deploying user must have `functions.bindings.create:{service}` permission to create bindings. | |
| operationId: deployFunction | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - name | |
| - code | |
| properties: | |
| name: | |
| type: string | |
| description: Function name | |
| example: my-function | |
| code: | |
| type: string | |
| description: | | |
| Complete JavaScript function code. Must be an async function named `handler` | |
| that accepts (request, context) parameters. | |
| example: | | |
| async function handler(request, context) { | |
| return { | |
| statusCode: 200, | |
| body: { message: 'Hello from ' + context.functionName } | |
| }; | |
| } | |
| methods: | |
| type: array | |
| description: Optional array of allowed HTTP methods. If not specified, all methods are allowed. | |
| items: | |
| type: string | |
| enum: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS] | |
| example: ["GET", "POST"] | |
| bindings: | |
| type: array | |
| description: | | |
| Optional array of service bindings. Each function gets a dedicated service account | |
| with minimal permissions based on declared bindings. Requires IdentityService to be configured. | |
| items: | |
| type: object | |
| required: | |
| - service | |
| - permissions | |
| properties: | |
| service: | |
| type: string | |
| description: Service name to bind to | |
| enum: [databases, storage, observability, sites, functions] | |
| example: databases | |
| permissions: | |
| type: array | |
| description: Array of permission declarations | |
| items: | |
| type: object | |
| properties: | |
| resource: | |
| type: string | |
| description: Resource type (e.g., "table", "bucket"). Optional - omit for service-level access. | |
| example: table | |
| actions: | |
| type: array | |
| description: Array of actions (e.g., ["read", "write"]). Defaults to ["*"] if not specified. | |
| items: | |
| type: string | |
| example: ["read", "write"] | |
| targets: | |
| type: array | |
| description: Specific resource names. Optional - omit for resource-level access to all resources. | |
| items: | |
| type: string | |
| example: ["users-table", "posts-table"] | |
| example: | |
| - service: databases | |
| permissions: | |
| - resource: table | |
| actions: ["read", "write"] | |
| targets: ["users-table"] | |
| - service: storage | |
| permissions: | |
| - resource: bucket | |
| actions: ["write"] | |
| responses: | |
| '201': | |
| description: Function deployed successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| function: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| description: Function ID | |
| name: | |
| type: string | |
| description: Function name | |
| endpoint: | |
| type: string | |
| description: Function execution endpoint | |
| methods: | |
| type: array | |
| description: Allowed HTTP methods (if restricted) | |
| items: | |
| type: string | |
| bindings: | |
| type: array | |
| description: Service bindings (if configured) | |
| items: | |
| type: object | |
| properties: | |
| service: | |
| type: string | |
| permissions: | |
| type: array | |
| items: | |
| type: object | |
| serviceAccountId: | |
| type: string | |
| description: Service account ID for bindings (if configured). Token is never exposed. | |
| createdAt: | |
| type: string | |
| format: date-time | |
| description: Creation timestamp | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /functions/{functionId}: | |
| get: | |
| tags: | |
| - Functions | |
| summary: Get function | |
| description: Returns function details | |
| operationId: getFunction | |
| parameters: | |
| - $ref: '#/components/parameters/FunctionId' | |
| responses: | |
| '200': | |
| description: Function details | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| function: | |
| $ref: '#/components/schemas/Function' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| put: | |
| tags: | |
| - Functions | |
| summary: Update function | |
| description: Updates function code, HTTP method restrictions, and/or service bindings. At least one of code, methods, or bindings must be provided. | |
| operationId: updateFunction | |
| parameters: | |
| - $ref: '#/components/parameters/FunctionId' | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| code: | |
| type: string | |
| description: Updated function code | |
| methods: | |
| type: array | |
| description: Updated HTTP method restrictions. Pass empty array to remove restrictions. | |
| items: | |
| type: string | |
| enum: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS] | |
| example: ["GET", "POST"] | |
| bindings: | |
| type: array | |
| description: | | |
| Updated service bindings. Updates the function's service account role permissions. | |
| Requires IdentityService to be configured. | |
| items: | |
| type: object | |
| required: | |
| - service | |
| - permissions | |
| properties: | |
| service: | |
| type: string | |
| enum: [databases, storage, observability, sites, functions] | |
| permissions: | |
| type: array | |
| items: | |
| type: object | |
| properties: | |
| resource: | |
| type: string | |
| actions: | |
| type: array | |
| items: | |
| type: string | |
| targets: | |
| type: array | |
| items: | |
| type: string | |
| minProperties: 1 | |
| responses: | |
| '200': | |
| description: Function updated successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| function: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| description: Function ID | |
| name: | |
| type: string | |
| description: Function name | |
| endpoint: | |
| type: string | |
| description: Function execution endpoint | |
| methods: | |
| type: array | |
| description: Allowed HTTP methods (if restricted) | |
| items: | |
| type: string | |
| updatedAt: | |
| type: string | |
| format: date-time | |
| description: Last update timestamp | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| delete: | |
| tags: | |
| - Functions | |
| summary: Delete function | |
| description: Deletes a deployed function | |
| operationId: deleteFunction | |
| parameters: | |
| - $ref: '#/components/parameters/FunctionId' | |
| responses: | |
| '200': | |
| description: Function deleted successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| message: | |
| type: string | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /functions/{functionId}/config: | |
| get: | |
| tags: | |
| - Functions | |
| summary: Get function configuration | |
| description: Returns function details including the source code | |
| operationId: getFunctionConfig | |
| parameters: | |
| - $ref: '#/components/parameters/FunctionId' | |
| responses: | |
| '200': | |
| description: Function configuration | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| function: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| description: Function ID | |
| name: | |
| type: string | |
| description: Function name | |
| endpoint: | |
| type: string | |
| description: Function execution endpoint | |
| filePath: | |
| type: string | |
| description: Path to the function file on disk | |
| code: | |
| type: string | |
| description: Function source code | |
| createdAt: | |
| type: string | |
| format: date-time | |
| description: Creation timestamp | |
| updatedAt: | |
| type: string | |
| format: date-time | |
| description: Last update timestamp | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| '500': | |
| description: Failed to read function code | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| error: | |
| type: string | |
| message: | |
| type: string | |
| /functions/stats: | |
| get: | |
| tags: | |
| - Functions | |
| summary: Get function statistics | |
| description: Returns statistics about deployed functions | |
| operationId: getFunctionStats | |
| responses: | |
| '200': | |
| description: Function statistics | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| stats: | |
| type: object | |
| properties: | |
| totalFunctions: | |
| type: number | |
| functions: | |
| type: array | |
| items: | |
| type: object | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /functions/run/{functionId}: | |
| get: | |
| tags: | |
| - Functions | |
| summary: Execute function (GET) | |
| description: | | |
| Executes a function with GET request. May return 405 if function has HTTP method restrictions. | |
| Wildcard Paths: Functions support wildcard paths. You can append any path after the functionId (e.g., `/functions/run/{functionId}/api/users/123`), and the function will receive the additional path in `context.request.subpath`. This allows deploying bundled APIs with their own internal routing. | |
| operationId: executeFunctionGet | |
| parameters: | |
| - $ref: '#/components/parameters/FunctionId' | |
| responses: | |
| '200': | |
| description: Function executed successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: true | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| '405': | |
| description: Method not allowed - function has HTTP method restrictions | |
| headers: | |
| Allow: | |
| schema: | |
| type: string | |
| description: Comma-separated list of allowed HTTP methods | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| error: | |
| type: string | |
| example: Method Not Allowed | |
| message: | |
| type: string | |
| example: This function only accepts GET, POST | |
| '500': | |
| description: Function execution error | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Error' | |
| post: | |
| tags: | |
| - Functions | |
| summary: Execute function (POST) | |
| description: | | |
| Executes a function with POST request and body. May return 405 if function has HTTP method restrictions. | |
| Wildcard Paths: Functions support wildcard paths. You can append any path after the functionId (e.g., `/functions/run/{functionId}/api/users`), and the function will receive the additional path in `context.request.subpath`. This allows deploying bundled APIs with their own internal routing. | |
| operationId: executeFunctionPost | |
| parameters: | |
| - $ref: '#/components/parameters/FunctionId' | |
| requestBody: | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: true | |
| responses: | |
| '200': | |
| description: Function executed successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| additionalProperties: true | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| '405': | |
| description: Method not allowed - function has HTTP method restrictions | |
| headers: | |
| Allow: | |
| schema: | |
| type: string | |
| description: Comma-separated list of allowed HTTP methods | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| error: | |
| type: string | |
| example: Method Not Allowed | |
| message: | |
| type: string | |
| example: This function only accepts GET, POST | |
| '500': | |
| description: Function execution error | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Error' | |
| # Storage Endpoints (Proxied) | |
| /storage/buckets: | |
| get: | |
| tags: | |
| - Storage | |
| summary: List buckets | |
| description: Returns all storage buckets | |
| operationId: listBuckets | |
| responses: | |
| '200': | |
| description: List of buckets | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| buckets: | |
| type: array | |
| items: | |
| type: string | |
| description: Array of bucket names | |
| example: | |
| buckets: ['my-bucket-1', 'my-bucket-2', 'my-bucket-3'] | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /storage/buckets/{bucket}: | |
| get: | |
| tags: | |
| - Storage | |
| summary: Get bucket statistics | |
| description: Returns statistics about a bucket including object count and total size | |
| operationId: getBucketStats | |
| parameters: | |
| - $ref: '#/components/parameters/BucketName' | |
| responses: | |
| '200': | |
| description: Bucket statistics | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| bucket: | |
| type: string | |
| description: Bucket name | |
| example: 'my-bucket' | |
| objectCount: | |
| type: number | |
| description: Total number of objects in the bucket | |
| example: 42 | |
| totalSize: | |
| type: number | |
| description: Total size of all objects in bytes | |
| example: 1048576 | |
| example: | |
| bucket: 'my-bucket' | |
| objectCount: 42 | |
| totalSize: 1048576 | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| description: Bucket not found | |
| content: | |
| application/json: | |
| schema: | |
| type: string | |
| example: 'Bucket not found' | |
| '500': | |
| description: Internal server error | |
| content: | |
| application/json: | |
| schema: | |
| type: string | |
| example: 'Internal server error' | |
| post: | |
| tags: | |
| - Storage | |
| summary: Create bucket | |
| description: Creates a new storage bucket | |
| operationId: createBucket | |
| parameters: | |
| - $ref: '#/components/parameters/BucketName' | |
| responses: | |
| '200': | |
| description: Bucket created successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| bucket: | |
| type: string | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| delete: | |
| tags: | |
| - Storage | |
| summary: Delete bucket | |
| description: Deletes a storage bucket | |
| operationId: deleteBucket | |
| parameters: | |
| - $ref: '#/components/parameters/BucketName' | |
| responses: | |
| '200': | |
| description: Bucket deleted successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| bucket: | |
| type: string | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /storage/buckets/{bucket}/objects: | |
| get: | |
| tags: | |
| - Storage | |
| summary: List objects in bucket | |
| description: | | |
| Lists objects in a bucket with S3-style prefix filtering for hierarchical navigation. | |
| Behavior: | |
| - Without prefix: Shows immediate children at bucket root (files + virtual folders) | |
| - With prefix: Shows immediate children within that prefix path | |
| - Virtual folders are created from common prefixes (objects grouped by first path segment) | |
| - Only shows one level deep - nested objects are represented as folders | |
| Example: | |
| For a bucket containing `file.txt`, `docs/readme.md`, and `docs/api/spec.json`: | |
| - No prefix: Returns `file.txt` (file) and `docs/` (folder) | |
| - Prefix `docs/`: Returns `readme.md` (file) and `api/` (folder) | |
| - Prefix `docs/api/`: Returns `spec.json` (file) | |
| Objects include metadata: size, modification time, and type (file/folder). | |
| Folders end with a trailing slash (/). | |
| operationId: listObjects | |
| parameters: | |
| - $ref: '#/components/parameters/BucketName' | |
| - name: prefix | |
| in: query | |
| required: false | |
| schema: | |
| type: string | |
| description: | | |
| S3-style prefix filter for hierarchical navigation. | |
| Returns only immediate children under this path. | |
| Omit or use empty string for bucket root. | |
| Examples: | |
| - '' or omitted: Root level | |
| - 'docs/': Objects directly under docs/ | |
| - 'docs/api/': Objects directly under docs/api/ | |
| example: 'docs/' | |
| responses: | |
| '200': | |
| description: List of objects | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| objects: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/StorageObject' | |
| description: Array of objects with metadata | |
| prefix: | |
| type: string | |
| description: The prefix used for filtering (echoed from query) | |
| examples: | |
| rootLevel: | |
| summary: List root level objects | |
| value: | |
| objects: | |
| - key: 'docs/' | |
| size: 0 | |
| lastModified: '2025-12-19T13:45:00.000Z' | |
| type: 'folder' | |
| - key: 'file.txt' | |
| size: 1234 | |
| lastModified: '2025-12-19T13:45:00.000Z' | |
| type: 'file' | |
| prefix: '' | |
| withPrefix: | |
| summary: List objects in folder | |
| value: | |
| objects: | |
| - key: 'subfolder/' | |
| size: 0 | |
| lastModified: '2025-12-19T13:45:00.000Z' | |
| type: 'folder' | |
| - key: 'readme.md' | |
| size: 5678 | |
| lastModified: '2025-12-19T13:45:00.000Z' | |
| type: 'file' | |
| prefix: 'docs/' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| description: Bucket not found | |
| content: | |
| application/json: | |
| schema: | |
| type: string | |
| example: 'Bucket not found' | |
| '500': | |
| description: Internal server error | |
| content: | |
| application/json: | |
| schema: | |
| type: string | |
| example: 'Internal server error' | |
| put: | |
| tags: | |
| - Storage | |
| summary: Upload object | |
| description: | | |
| Uploads/creates an object in a bucket. | |
| Supported upload methods: | |
| 1. JSON upload (for text content): Send JSON with `key` and `content` fields | |
| 2. Binary upload with query param: Send raw binary with `?key=path/to/file` query parameter | |
| 3. Multipart form upload: Send multipart/form-data with `file` and `key` fields | |
| For binary files (images, videos, etc.), use method 2 or 3 to avoid corruption. | |
| operationId: putObject | |
| parameters: | |
| - $ref: '#/components/parameters/BucketName' | |
| - name: key | |
| in: query | |
| required: false | |
| schema: | |
| type: string | |
| description: | | |
| Object key/path (required for binary uploads). | |
| Use this for application/octet-stream or other binary content types. | |
| example: 'images/photo.jpg' | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - key | |
| - content | |
| properties: | |
| key: | |
| type: string | |
| description: Object key/path | |
| example: 'documents/readme.txt' | |
| content: | |
| type: string | |
| description: Object content (text) | |
| example: 'Hello, World!' | |
| multipart/form-data: | |
| schema: | |
| type: object | |
| required: | |
| - key | |
| - file | |
| properties: | |
| key: | |
| type: string | |
| description: Object key/path | |
| example: 'images/photo.jpg' | |
| file: | |
| type: string | |
| format: binary | |
| description: The file to upload | |
| application/octet-stream: | |
| schema: | |
| type: string | |
| format: binary | |
| description: Raw binary data (use ?key=path query parameter) | |
| responses: | |
| '200': | |
| description: Object uploaded successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| bucket: | |
| type: string | |
| key: | |
| type: string | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| post: | |
| tags: | |
| - Storage | |
| summary: Get object | |
| description: Retrieves an object from a bucket | |
| operationId: getObject | |
| parameters: | |
| - $ref: '#/components/parameters/BucketName' | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - key | |
| properties: | |
| key: | |
| type: string | |
| responses: | |
| '200': | |
| description: Object retrieved successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| bucket: | |
| type: string | |
| key: | |
| type: string | |
| content: | |
| type: string | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| delete: | |
| tags: | |
| - Storage | |
| summary: Delete object | |
| description: Deletes an object from a bucket | |
| operationId: deleteObject | |
| parameters: | |
| - $ref: '#/components/parameters/BucketName' | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - key | |
| properties: | |
| key: | |
| type: string | |
| responses: | |
| '200': | |
| description: Object deleted successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| bucket: | |
| type: string | |
| key: | |
| type: string | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| # Sites Endpoints (Proxied) | |
| /sites/projects: | |
| get: | |
| tags: | |
| - Sites | |
| summary: List static sites | |
| description: Returns all deployed static site projects | |
| operationId: listSites | |
| responses: | |
| '200': | |
| description: List of deployed sites | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| count: | |
| type: number | |
| projects: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/SiteProject' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| post: | |
| tags: | |
| - Sites | |
| summary: Deploy static site | |
| description: Uploads and deploys a static site project | |
| operationId: deploySite | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - files | |
| properties: | |
| projectId: | |
| type: string | |
| description: Optional project ID (auto-generated if not provided) | |
| files: | |
| type: array | |
| items: | |
| type: object | |
| required: | |
| - path | |
| - content | |
| properties: | |
| path: | |
| type: string | |
| description: File path relative to project root | |
| content: | |
| type: string | |
| description: Base64-encoded file content | |
| responses: | |
| '200': | |
| description: Site deployed successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| projectId: | |
| type: string | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /sites/projects/{projectId}: | |
| delete: | |
| tags: | |
| - Sites | |
| summary: Delete static site | |
| description: Deletes a static site project | |
| operationId: deleteSite | |
| parameters: | |
| - $ref: '#/components/parameters/ProjectId' | |
| responses: | |
| '200': | |
| description: Site deleted successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| projectId: | |
| type: string | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| /sites/projects/{projectId}/{filepath}: | |
| get: | |
| tags: | |
| - Sites | |
| summary: Serve static file | |
| description: Serves a static file from a deployed project | |
| operationId: serveStaticFile | |
| parameters: | |
| - $ref: '#/components/parameters/ProjectId' | |
| - name: filepath | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: File path within the project | |
| responses: | |
| '200': | |
| description: File served successfully | |
| content: | |
| text/html: | |
| schema: | |
| type: string | |
| text/css: | |
| schema: | |
| type: string | |
| application/javascript: | |
| schema: | |
| type: string | |
| image/png: | |
| schema: | |
| type: string | |
| format: binary | |
| '404': | |
| $ref: '#/components/responses/NotFound' | |
| # Observability Endpoints (Proxied) | |
| /observability/events: | |
| get: | |
| tags: | |
| - Observability | |
| summary: Query logs | |
| description: Retrieves log events with optional filtering | |
| operationId: queryLogs | |
| parameters: | |
| - name: startTime | |
| in: query | |
| schema: | |
| type: number | |
| format: int64 | |
| description: Start timestamp (milliseconds) | |
| - name: endTime | |
| in: query | |
| schema: | |
| type: number | |
| format: int64 | |
| description: End timestamp (milliseconds) | |
| - name: service | |
| in: query | |
| schema: | |
| type: string | |
| description: Filter by service name | |
| - name: level | |
| in: query | |
| schema: | |
| type: string | |
| enum: [info, warn, error, debug] | |
| description: Filter by log level | |
| - name: limit | |
| in: query | |
| schema: | |
| type: number | |
| default: 1000 | |
| description: Maximum number of events to return | |
| - name: offset | |
| in: query | |
| schema: | |
| type: number | |
| default: 0 | |
| description: Offset for pagination | |
| responses: | |
| '200': | |
| description: Log events retrieved successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| count: | |
| type: number | |
| events: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/LogEvent' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| post: | |
| tags: | |
| - Observability | |
| summary: Log event | |
| description: Creates a new log event | |
| operationId: logEvent | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - service | |
| - level | |
| - message | |
| properties: | |
| service: | |
| type: string | |
| level: | |
| type: string | |
| enum: [info, warn, error, debug] | |
| message: | |
| type: string | |
| metadata: | |
| type: object | |
| additionalProperties: true | |
| responses: | |
| '200': | |
| description: Event logged successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| event: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| timestamp: | |
| type: number | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /observability/stats: | |
| get: | |
| tags: | |
| - Observability | |
| summary: Get log statistics | |
| description: Returns statistics about stored logs | |
| operationId: getLogStats | |
| responses: | |
| '200': | |
| description: Log statistics | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| stats: | |
| type: object | |
| properties: | |
| totalLogFiles: | |
| type: number | |
| logFiles: | |
| type: array | |
| items: | |
| type: object | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /observability/events/cleanup: | |
| delete: | |
| tags: | |
| - Observability | |
| summary: Cleanup old logs | |
| description: Deletes logs older than specified days | |
| operationId: cleanupLogs | |
| requestBody: | |
| required: true | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| required: | |
| - olderThanDays | |
| properties: | |
| olderThanDays: | |
| type: number | |
| description: Delete logs older than this many days | |
| responses: | |
| '200': | |
| description: Logs cleaned up successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| deletedCount: | |
| type: number | |
| '400': | |
| $ref: '#/components/responses/BadRequest' | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| /observability/flush: | |
| post: | |
| tags: | |
| - Observability | |
| summary: Flush log buffer | |
| description: Forces write buffer to flush to disk | |
| operationId: flushLogs | |
| responses: | |
| '200': | |
| description: Buffer flushed successfully | |
| content: | |
| application/json: | |
| schema: | |
| type: object | |
| properties: | |
| success: | |
| type: boolean | |
| '401': | |
| $ref: '#/components/responses/Unauthorized' | |
| components: | |
| securitySchemes: | |
| BearerAuth: | |
| type: http | |
| scheme: bearer | |
| bearerFormat: JWT | |
| description: JWT token obtained from authentication flow | |
| ServiceAccountAuth: | |
| type: http | |
| scheme: bearer | |
| bearerFormat: API Key | |
| description: Service account API key in format 'sa.{id}.{key}' | |
| parameters: | |
| UserId: | |
| name: userId | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: User identity ID | |
| ServiceAccountId: | |
| name: serviceAccountId | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Service account identity ID | |
| ServiceName: | |
| name: serviceName | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Service name | |
| FunctionId: | |
| name: functionId | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Function ID (SHA256 hash) | |
| BucketName: | |
| name: bucket | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Bucket name | |
| ProjectId: | |
| name: projectId | |
| in: path | |
| required: true | |
| schema: | |
| type: string | |
| description: Static site project ID | |
| schemas: | |
| RoleId: | |
| type: string | |
| description: Role identifier (can be built-in like 'administrator' or 'user', or custom role ID) | |
| example: administrator | |
| Identity: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| description: Unique identity ID | |
| name: | |
| type: string | |
| description: Display name | |
| type: | |
| type: string | |
| enum: [user, service_account] | |
| description: Identity type | |
| roles: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/RoleId' | |
| description: Assigned roles | |
| metadata: | |
| type: object | |
| properties: | |
| email: | |
| type: string | |
| format: email | |
| description: User email (for user type) | |
| description: | |
| type: string | |
| description: Description (for service account type) | |
| active: | |
| type: boolean | |
| description: Account active status | |
| createdAt: | |
| type: string | |
| format: date-time | |
| lastLogin: | |
| type: string | |
| format: date-time | |
| additionalProperties: true | |
| EnrichedIdentity: | |
| allOf: | |
| - $ref: '#/components/schemas/Identity' | |
| - type: object | |
| properties: | |
| enrichedRoles: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Role' | |
| description: Full role objects with policies | |
| Role: | |
| type: object | |
| properties: | |
| id: | |
| $ref: '#/components/schemas/RoleId' | |
| name: | |
| type: string | |
| description: | |
| type: string | |
| policies: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/Policy' | |
| constraints: | |
| $ref: '#/components/schemas/Constraints' | |
| Constraints: | |
| type: object | |
| properties: | |
| assumable_by: | |
| type: object | |
| properties: | |
| identities: | |
| type: array | |
| items: | |
| type: string | |
| description: List of identity IDs that can assume this role | |
| roles: | |
| type: array | |
| items: | |
| type: string | |
| description: List of role IDs whose members can assume this role | |
| services: | |
| type: array | |
| items: | |
| type: string | |
| description: List of services that can assume this role | |
| assumption_constraints: | |
| type: object | |
| properties: | |
| max_duration: | |
| type: number | |
| description: Maximum duration in seconds for role assumption | |
| require_reason: | |
| type: boolean | |
| description: Whether a reason is required for assuming this role | |
| audit_level: | |
| type: string | |
| enum: [low, medium, high] | |
| description: Audit level for role assumption | |
| Policy: | |
| type: object | |
| properties: | |
| effect: | |
| type: string | |
| enum: [allow, deny] | |
| actions: | |
| type: array | |
| items: | |
| type: string | |
| description: Actions (supports wildcards) | |
| example: ['identity.user.create', 'identity.*.get'] | |
| targets: | |
| type: array | |
| items: | |
| type: string | |
| description: Target resources (supports wildcards) | |
| example: ['service:identity', '*'] | |
| PredefinedServiceRegistration: | |
| type: object | |
| required: | |
| - name | |
| properties: | |
| name: | |
| type: string | |
| enum: [storage, functions, sites, databases, observability] | |
| description: | | |
| Name of the predefined service to register. Each predefined service comes with default configuration | |
| port: | |
| type: number | |
| minimum: 1 | |
| maximum: 65535 | |
| description: Override default service port | |
| prefix: | |
| type: string | |
| pattern: '^/' | |
| description: Override default API path prefix | |
| args: | |
| type: array | |
| items: | |
| type: string | |
| description: Override default command line arguments | |
| restartPolicy: | |
| $ref: '#/components/schemas/RestartPolicy' | |
| healthCheck: | |
| $ref: '#/components/schemas/HealthCheck' | |
| ServiceConfig: | |
| type: object | |
| required: | |
| - name | |
| - path | |
| - port | |
| - prefix | |
| properties: | |
| name: | |
| type: string | |
| description: Unique service name | |
| path: | |
| type: string | |
| description: Path to compiled Node.js module | |
| port: | |
| type: number | |
| minimum: 1 | |
| maximum: 65535 | |
| description: Service port | |
| prefix: | |
| type: string | |
| pattern: '^/' | |
| description: API path prefix | |
| example: /databases | |
| active: | |
| type: boolean | |
| default: true | |
| description: Whether service is active | |
| args: | |
| type: array | |
| items: | |
| type: string | |
| description: Command line arguments | |
| restartPolicy: | |
| $ref: '#/components/schemas/RestartPolicy' | |
| healthCheck: | |
| $ref: '#/components/schemas/HealthCheck' | |
| RestartPolicy: | |
| type: object | |
| properties: | |
| type: | |
| type: string | |
| enum: [always, on-failure, never] | |
| maxAttempts: | |
| type: number | |
| description: Max restart attempts (0 = unlimited) | |
| backoff: | |
| type: number | |
| description: Delay between restarts (milliseconds) | |
| HealthCheck: | |
| type: object | |
| properties: | |
| path: | |
| type: string | |
| description: Health check endpoint path | |
| example: /health | |
| interval: | |
| type: number | |
| description: Check interval (milliseconds) | |
| timeout: | |
| type: number | |
| description: Request timeout (milliseconds) | |
| failureThreshold: | |
| type: number | |
| description: Consecutive failures to mark unhealthy | |
| successThreshold: | |
| type: number | |
| description: Consecutive successes to mark healthy | |
| restartOnFailure: | |
| type: boolean | |
| description: Auto-restart on health check failure | |
| healthy: | |
| type: boolean | |
| description: Current health status (runtime) | |
| Function: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| description: Function ID (SHA256 hash) | |
| name: | |
| type: string | |
| description: Function name | |
| endpoint: | |
| type: string | |
| description: Function execution endpoint | |
| filePath: | |
| type: string | |
| description: Path to the function file | |
| methods: | |
| type: array | |
| items: | |
| type: string | |
| enum: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS] | |
| description: Allowed HTTP methods for this function. If not specified, all methods are allowed. | |
| example: ["GET", "POST"] | |
| bindings: | |
| type: array | |
| description: Service bindings configuration (if configured) | |
| items: | |
| type: object | |
| required: | |
| - service | |
| - permissions | |
| properties: | |
| service: | |
| type: string | |
| enum: [databases, storage, observability, sites, functions] | |
| description: Service name | |
| permissions: | |
| type: array | |
| description: Permission declarations for this service | |
| items: | |
| type: object | |
| properties: | |
| resource: | |
| type: string | |
| description: Resource type (optional) | |
| actions: | |
| type: array | |
| items: | |
| type: string | |
| description: Actions array (optional) | |
| targets: | |
| type: array | |
| items: | |
| type: string | |
| description: Specific resource targets (optional) | |
| serviceAccountId: | |
| type: string | |
| description: Service account ID for bindings (if configured). Token is never exposed in API responses. | |
| createdAt: | |
| type: number | |
| format: int64 | |
| description: Creation timestamp | |
| updatedAt: | |
| type: number | |
| format: int64 | |
| description: Last update timestamp | |
| LogEvent: | |
| type: object | |
| properties: | |
| id: | |
| type: string | |
| description: Event ID | |
| timestamp: | |
| type: number | |
| format: int64 | |
| description: Event timestamp (milliseconds) | |
| service: | |
| type: string | |
| description: Service name | |
| level: | |
| type: string | |
| enum: [info, warn, error, debug] | |
| description: Log level | |
| message: | |
| type: string | |
| description: Log message | |
| metadata: | |
| type: object | |
| additionalProperties: true | |
| description: Additional event metadata | |
| StorageObject: | |
| type: object | |
| properties: | |
| key: | |
| type: string | |
| description: | | |
| Object key (path). | |
| Files have their name/path, folders end with a trailing slash (/). | |
| example: 'docs/readme.md' | |
| size: | |
| type: number | |
| format: int64 | |
| description: | | |
| Object size in bytes. | |
| Folders always have size 0. | |
| example: 1234 | |
| lastModified: | |
| type: string | |
| format: date-time | |
| description: Last modification timestamp | |
| example: '2025-12-19T13:45:00.000Z' | |
| type: | |
| type: string | |
| enum: [file, folder] | |
| description: Object type either file or folder | |
| example: 'file' | |
| required: | |
| - key | |
| - size | |
| - lastModified | |
| - type | |
| SiteProject: | |
| type: object | |
| properties: | |
| projectId: | |
| type: string | |
| description: Unique project identifier | |
| example: 'a1b2c3d4' | |
| name: | |
| type: string | |
| description: Project display name (derived from projectId or index.html title) | |
| example: 'My Static Site' | |
| url: | |
| type: string | |
| description: Public URL for the deployed site (via gateway) | |
| example: 'http://localhost:3000/sites/projects/a1b2c3d4/' | |
| status: | |
| type: string | |
| enum: [active, inactive, deploying, failed] | |
| description: Deployment status | |
| example: 'active' | |
| files: | |
| type: number | |
| description: Number of files in the deployment | |
| example: 12 | |
| size: | |
| type: string | |
| description: Total size of deployed files (human-readable format) | |
| example: '2.5 MB' | |
| lastDeployed: | |
| type: string | |
| format: date-time | |
| description: Last deployment timestamp | |
| example: '2025-12-19T13:45:00.000Z' | |
| createdAt: | |
| type: string | |
| format: date-time | |
| description: Project creation timestamp | |
| example: '2025-12-19T10:30:00.000Z' | |
| required: | |
| - projectId | |
| - url | |
| - status | |
| DatabaseTable: | |
| type: object | |
| properties: | |
| name: | |
| type: string | |
| description: Table name | |
| example: 'users' | |
| items: | |
| type: number | |
| description: Number of items in the table | |
| example: 150 | |
| size: | |
| type: string | |
| description: Human-readable size of the table | |
| example: '2.3 KB' | |
| required: | |
| - name | |
| - items | |
| - size | |
| Error: | |
| type: object | |
| properties: | |
| error: | |
| type: string | |
| description: Error message | |
| cause: | |
| type: object | |
| properties: | |
| statusCode: | |
| type: number | |
| responses: | |
| BadRequest: | |
| description: Bad request | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Error' | |
| example: | |
| error: Invalid input | |
| cause: | |
| statusCode: 400 | |
| Unauthorized: | |
| description: Unauthorized - Invalid or missing authentication | |
| content: | |
| text/plain: | |
| schema: | |
| type: string | |
| example: Unauthorized | |
| Forbidden: | |
| description: Forbidden - Insufficient permissions | |
| content: | |
| text/plain: | |
| schema: | |
| type: string | |
| example: Forbidden | |
| NotFound: | |
| description: Resource not found | |
| content: | |
| text/plain: | |
| schema: | |
| type: string | |
| example: Not Found | |
| ServiceUnavailable: | |
| description: Service unavailable | |
| content: | |
| application/json: | |
| schema: | |
| $ref: '#/components/schemas/Error' | |
| example: | |
| error: Service unavailable (unhealthy) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment