/ specs / diagnostic-api.yml
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