diagnostic-api.yml
1 openapi: 3.1.0 2 info: 3 title: OpenSandbox Diagnostics API 4 version: 0.1.0 5 description: | 6 The OpenSandbox Diagnostics API exposes best-effort plain-text diagnostic 7 snapshots for a sandbox. It is intended for humans and troubleshooting agents 8 that need to collect runtime troubleshooting material without depending on a 9 stable structured observability model. 10 11 This API is not an audit log API and does not define the canonical 12 observability schema for OpenSandbox. Structured telemetry, long-term 13 retention, filtering, pagination, and streaming may be provided separately. 14 15 Successful responses return a JSON descriptor whose diagnostic payload is 16 either embedded inline or made available through a download URL. The diagnostic 17 payload itself is display-oriented `text/plain` content. Clients should not 18 parse individual payload lines as a stable schema. Servers may impose 19 implementation-defined retention and response size limits. 20 21 ## Authentication 22 23 API Key authentication is required for all operations: 24 25 1. **HTTP Header** 26 ``` 27 OPEN-SANDBOX-API-KEY: your-api-key 28 ``` 29 30 2. **Environment Variable** (for SDK clients) 31 ``` 32 OPEN_SANDBOX_API_KEY=your-api-key 33 ``` 34 35 SDK clients will automatically pick up this environment variable. 36 servers: 37 - url: http://localhost:8080/v1 38 description: Local development 39 security: 40 - apiKeyAuth: [] 41 tags: 42 - name: Diagnostics 43 description: Sandbox troubleshooting payload descriptors 44 paths: 45 /sandboxes/{sandboxId}/diagnostics/logs: 46 get: 47 tags: [Diagnostics] 48 summary: Get diagnostic logs 49 description: | 50 Retrieve a best-effort descriptor for sandbox diagnostic log text. 51 52 Logs are not limited to a structured observability model. Depending on the 53 selected `scope` and server configuration, log text may include sandbox 54 container stdout/stderr, lifecycle diagnostic text, network diagnostic text, 55 or other implementation-defined diagnostic material. 56 57 This endpoint does not provide streaming, pagination, or a stable line-level 58 schema in this version. The server returns a JSON descriptor for currently 59 available diagnostic text for the requested scope, subject to 60 implementation-defined retention and response size limits. The descriptor 61 either embeds the text as `content` or returns a `contentUrl` where the 62 text can be downloaded. 63 parameters: 64 - $ref: '#/components/parameters/SandboxId' 65 - $ref: '#/components/parameters/DiagnosticScope' 66 responses: 67 '200': 68 description: Diagnostic log content descriptor 69 content: 70 application/json: 71 schema: 72 $ref: '#/components/schemas/DiagnosticContentResponse' 73 examples: 74 inline: 75 summary: Inline container log text 76 value: 77 sandboxId: sbx_123 78 kind: logs 79 scope: container 80 delivery: inline 81 contentType: text/plain; charset=utf-8 82 content: | 83 2026-03-25T10:01:13Z execd started 84 2026-03-25T10:01:14Z sandbox process ready 85 truncated: false 86 url: 87 summary: Downloadable container log text 88 value: 89 sandboxId: sbx_123 90 kind: logs 91 scope: container 92 delivery: url 93 contentType: text/plain; charset=utf-8 94 contentUrl: https://example.com/diagnostics/sbx_123/logs.txt 95 contentLength: 10485760 96 expiresAt: "2026-04-14T10:30:00Z" 97 truncated: false 98 headers: 99 X-Request-ID: 100 $ref: '#/components/headers/XRequestId' 101 '400': 102 $ref: '#/components/responses/BadRequest' 103 '401': 104 $ref: '#/components/responses/Unauthorized' 105 '403': 106 $ref: '#/components/responses/Forbidden' 107 '404': 108 $ref: '#/components/responses/NotFound' 109 '500': 110 $ref: '#/components/responses/InternalServerError' 111 /sandboxes/{sandboxId}/diagnostics/events: 112 get: 113 tags: [Diagnostics] 114 summary: Get diagnostic events 115 description: | 116 Retrieve a best-effort descriptor for sandbox diagnostic event text. 117 118 Events are rendered as diagnostic text rather than exposed as a stable 119 structured event model. Depending on the selected `scope` and runtime, event 120 text may include lifecycle transitions, runtime or platform events such as 121 Kubernetes Events, network diagnostic events, process activity events, or 122 other implementation-defined event material. 123 124 This endpoint does not provide streaming, pagination, or a stable line-level 125 schema in this version. The server returns a JSON descriptor for currently 126 available diagnostic event text for the requested scope, subject to 127 implementation-defined retention and response size limits. The descriptor 128 either embeds the text as `content` or returns a `contentUrl` where the 129 text can be downloaded. 130 parameters: 131 - $ref: '#/components/parameters/SandboxId' 132 - $ref: '#/components/parameters/DiagnosticScope' 133 responses: 134 '200': 135 description: Diagnostic event content descriptor 136 content: 137 application/json: 138 schema: 139 $ref: '#/components/schemas/DiagnosticContentResponse' 140 examples: 141 inline: 142 summary: Inline runtime event text 143 value: 144 sandboxId: sbx_123 145 kind: events 146 scope: runtime 147 delivery: inline 148 contentType: text/plain; charset=utf-8 149 content: | 150 2026-03-25T10:01:13Z runtime Normal Scheduled Successfully assigned sandbox pod 151 2026-03-25T10:01:14Z runtime Normal Pulled Container image pulled 152 truncated: false 153 url: 154 summary: Downloadable runtime event text 155 value: 156 sandboxId: sbx_123 157 kind: events 158 scope: runtime 159 delivery: url 160 contentType: text/plain; charset=utf-8 161 contentUrl: https://example.com/diagnostics/sbx_123/events.txt 162 contentLength: 5242880 163 expiresAt: "2026-04-14T10:30:00Z" 164 truncated: false 165 headers: 166 X-Request-ID: 167 $ref: '#/components/headers/XRequestId' 168 '400': 169 $ref: '#/components/responses/BadRequest' 170 '401': 171 $ref: '#/components/responses/Unauthorized' 172 '403': 173 $ref: '#/components/responses/Forbidden' 174 '404': 175 $ref: '#/components/responses/NotFound' 176 '500': 177 $ref: '#/components/responses/InternalServerError' 178 components: 179 securitySchemes: 180 apiKeyAuth: 181 type: apiKey 182 in: header 183 name: OPEN-SANDBOX-API-KEY 184 description: | 185 API Key for authentication. Can be provided via: 186 1. HTTP Header: OPEN-SANDBOX-API-KEY: your-api-key 187 2. Environment variable: OPEN_SANDBOX_API_KEY (for SDK clients) 188 parameters: 189 SandboxId: 190 name: sandboxId 191 in: path 192 required: true 193 description: Unique sandbox identifier 194 schema: 195 type: string 196 DiagnosticScope: 197 name: scope 198 in: query 199 required: false 200 description: | 201 Optional diagnostic scope selector. Known scopes may include `container`, 202 `lifecycle`, `runtime`, `network`, `process`, and `all`. Supported scopes 203 and defaults are implementation-defined; servers may add new scopes over 204 time. 205 schema: 206 type: string 207 examples: 208 container: 209 summary: Sandbox container diagnostics 210 value: container 211 runtime: 212 summary: Runtime or platform diagnostics 213 value: runtime 214 all: 215 summary: Best-effort aggregate across supported scopes 216 value: all 217 headers: 218 XRequestId: 219 description: Unique request identifier for tracing 220 schema: 221 type: string 222 format: uuid 223 responses: 224 BadRequest: 225 description: The request was invalid or malformed 226 content: 227 application/json: 228 schema: 229 $ref: '#/components/schemas/ErrorResponse' 230 headers: 231 X-Request-ID: 232 $ref: '#/components/headers/XRequestId' 233 Unauthorized: 234 description: Authentication credentials are missing or invalid 235 content: 236 application/json: 237 schema: 238 $ref: '#/components/schemas/ErrorResponse' 239 headers: 240 X-Request-ID: 241 $ref: '#/components/headers/XRequestId' 242 Forbidden: 243 description: The authenticated user lacks permission for this operation 244 content: 245 application/json: 246 schema: 247 $ref: '#/components/schemas/ErrorResponse' 248 headers: 249 X-Request-ID: 250 $ref: '#/components/headers/XRequestId' 251 NotFound: 252 description: The requested sandbox does not exist 253 content: 254 application/json: 255 schema: 256 $ref: '#/components/schemas/ErrorResponse' 257 headers: 258 X-Request-ID: 259 $ref: '#/components/headers/XRequestId' 260 InternalServerError: 261 description: An unexpected server error occurred 262 content: 263 application/json: 264 schema: 265 $ref: '#/components/schemas/ErrorResponse' 266 headers: 267 X-Request-ID: 268 $ref: '#/components/headers/XRequestId' 269 schemas: 270 DiagnosticContentResponse: 271 type: object 272 description: | 273 Descriptor for diagnostic text content. 274 275 When `delivery` is `inline`, servers MUST include `content` with the 276 diagnostic text and MUST omit `contentUrl` / `expiresAt`. 277 278 When `delivery` is `url`, servers MUST include `contentUrl` and `expiresAt` 279 to identify where the diagnostic text can be downloaded and MUST omit 280 `content`. 281 required: [sandboxId, kind, scope, delivery, contentType, truncated] 282 properties: 283 sandboxId: 284 type: string 285 description: Unique sandbox identifier. 286 kind: 287 type: string 288 description: Diagnostic payload kind. 289 enum: [logs, events] 290 scope: 291 type: string 292 description: Diagnostic scope used for this response. 293 delivery: 294 type: string 295 description: How the diagnostic text payload is delivered. 296 enum: [inline, url] 297 contentType: 298 type: string 299 description: Media type of the diagnostic payload. 300 examples: ["text/plain; charset=utf-8"] 301 content: 302 type: string 303 description: Inline diagnostic text payload. Present when `delivery` is `inline`. 304 contentUrl: 305 type: string 306 format: uri 307 description: URL where the diagnostic text payload can be downloaded. Present when `delivery` is `url`. 308 contentLength: 309 type: integer 310 minimum: 0 311 description: Payload size in bytes when known. 312 expiresAt: 313 type: string 314 format: date-time 315 description: Expiration time for the download URL. Present when `delivery` is `url`. 316 truncated: 317 type: boolean 318 description: | 319 Whether the diagnostic payload returned inline or by URL was 320 intentionally truncated by the server. This does not indicate backend 321 retention gaps such as expired Kubernetes Events; those should be 322 reported through `warnings` when available. 323 warnings: 324 type: array 325 description: Non-fatal warnings about payload completeness or availability. 326 items: 327 type: string 328 additionalProperties: false 329 ErrorResponse: 330 type: object 331 description: | 332 Standard error response for all non-2xx HTTP responses. 333 HTTP status code indicates the error category; code and message provide details. 334 properties: 335 code: 336 type: string 337 description: Machine-readable error code. 338 message: 339 type: string 340 description: Human-readable error message describing what went wrong. 341 required: [code, message] 342 additionalProperties: false