{
  "openapi": "3.1.0",
  "info": {
    "title": "Mock API",
    "version": "1.0.0",
    "summary": "Upload JSON, get a URL, then make it slow, flaky or wrong on purpose.",
    "description": "A self-hosted mock API for testing clients against controlled responses. Plain Node.js, zero runtime dependencies.\n\n**Every route** accepts the query controls `delay`, `status`, `flaky`, `sequence`, `sequence_key`, `sequence_reset`, `header_<Name>` and `cors`. They are listed on each operation.\n\n**Every JSON response** except `GET /mock/{id}` uses the envelope `{ success, data | error, meta }`, and every response carries `X-Request-Id` and `Cache-Control: no-store` unless you opt into caching with `?header_Cache-Control=...`.\n\n**Browsers** can call every endpoint: CORS is on by default (`Access-Control-Allow-Origin: *`, preflights answered, custom headers exposed). Credentials are never allowed.",
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "servers": [
    {
      "url": "http://localhost:8001",
      "description": "This server"
    }
  ],
  "tags": [
    {
      "name": "Mocks",
      "description": "Store JSON and serve it back at a stable URL."
    },
    {
      "name": "Utilities",
      "description": "Endpoints for debugging what your client sends and receives."
    },
    {
      "name": "Sample data",
      "description": "Ready-made datasets for building UIs before the real API exists."
    },
    {
      "name": "System",
      "description": "Health and request information."
    }
  ],
  "paths": {
    "/upload": {
      "post": {
        "tags": [
          "Mocks"
        ],
        "summary": "Upload a mock",
        "description": "Stores any JSON value (object, array, string, number) and returns a URL that serves it. The body is stored minified by stripping whitespace only, so large integers, `2.50` and key order are kept exactly. Uploads expire after `TTL_MS` (24 h by default).\n\n**Save the `delete_token`:** only its hash is stored, and it is needed to update or delete the mock.\n\nCounts toward the per-IP write rate limit.",
        "operationId": "uploadMock",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Any valid UTF-8 JSON, up to `MAX_BODY_BYTES` (2 MB).",
          "content": {
            "application/json": {
              "schema": {},
              "example": {
                "user": {
                  "id": 42,
                  "name": "Aarav"
                },
                "roles": [
                  "admin"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Stored",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/UploadResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidJson"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/mock/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/MockId"
        }
      ],
      "get": {
        "tags": [
          "Mocks"
        ],
        "summary": "Fetch a mock",
        "description": "Returns the stored JSON exactly as saved, **not** wrapped in the envelope. Supports conditional requests: send the `ETag` back in `If-None-Match` to get `304 Not Modified`.\n\nAdd `?header_Cache-Control=no-cache` so browsers and HTTP libraries keep the response and revalidate it automatically.",
        "operationId": "getMock",
        "parameters": [
          {
            "$ref": "#/components/parameters/IfNoneMatch"
          },
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "The stored JSON",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "description": "Whatever was uploaded"
                },
                "example": {
                  "user": {
                    "id": 42,
                    "name": "Aarav"
                  },
                  "roles": [
                    "admin"
                  ]
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "404": {
            "$ref": "#/components/responses/MockNotFound"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      },
      "put": {
        "tags": [
          "Mocks"
        ],
        "summary": "Replace a mock",
        "description": "Replaces the stored JSON, resets the expiry to now + `TTL_MS`, and returns a new `ETag`. The ID, `created_at` and delete token never change.\n\nSend `If-Match` with the ETag you last read to avoid overwriting someone else's change: a stale ETag gets `412` and nothing is saved.",
        "operationId": "replaceMock",
        "security": [
          {
            "deleteToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {},
              "example": {
                "user": {
                  "id": 42,
                  "name": "Aarav Sharma"
                },
                "roles": [
                  "admin",
                  "editor"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Replaced",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/UpdateResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidJson"
          },
          "401": {
            "$ref": "#/components/responses/MissingToken"
          },
          "403": {
            "$ref": "#/components/responses/WrongToken"
          },
          "404": {
            "$ref": "#/components/responses/MockNotFound"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      },
      "delete": {
        "tags": [
          "Mocks"
        ],
        "summary": "Delete a mock",
        "description": "Deletes the mock immediately. `If-Match` is supported here too.",
        "operationId": "deleteMock",
        "security": [
          {
            "deleteToken": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IfMatch"
          },
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/MissingToken"
          },
          "403": {
            "$ref": "#/components/responses/WrongToken"
          },
          "404": {
            "$ref": "#/components/responses/MockNotFound"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/echo": {
      "post": {
        "tags": [
          "Utilities"
        ],
        "summary": "Echo the request back",
        "description": "Accepts **any method** and any body up to `MAX_BODY_BYTES`, stores nothing, and returns exactly what arrived: method, path, query (repeated keys as arrays), headers with their original casing and duplicates, and the body.\n\nJSON bodies come back as raw `text` plus parsed `json`; binary as `base64`; `multipart/form-data` is split into parts, with a SHA-256 hash for each file. Credentials are shown as sent.",
        "operationId": "echoRequest",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {},
              "example": {
                "id": 1
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The reflected request",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/EchoResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/blackhole": {
      "get": {
        "tags": [
          "Utilities"
        ],
        "summary": "GET into the blackhole",
        "description": "Accepts any body up to `MAX_BODY_BYTES`, stores nothing, and replies with one of the standard success outcomes for GET, picked at random: 200. Multipart and binary bodies are accepted but never parsed.",
        "operationId": "blackholeGet",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "Accepted into the blackhole",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/BlackholeResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          }
        }
      },
      "post": {
        "tags": [
          "Utilities"
        ],
        "summary": "POST into the blackhole",
        "description": "Accepts any body up to `MAX_BODY_BYTES`, stores nothing, and replies with one of the standard success outcomes for POST, picked at random: 201, 202. Multipart and binary bodies are accepted but never parsed.",
        "operationId": "blackholePost",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "*/*": {
              "schema": {},
              "example": {
                "anything": "goes"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Accepted into the blackhole",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/BlackholeResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Accepted into the blackhole",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/BlackholeResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          }
        }
      },
      "put": {
        "tags": [
          "Utilities"
        ],
        "summary": "PUT into the blackhole",
        "description": "Accepts any body up to `MAX_BODY_BYTES`, stores nothing, and replies with one of the standard success outcomes for PUT, picked at random: 200, 201, 204. Multipart and binary bodies are accepted but never parsed.",
        "operationId": "blackholePut",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "*/*": {
              "schema": {},
              "example": {
                "anything": "goes"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted into the blackhole",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/BlackholeResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Accepted into the blackhole",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/BlackholeResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "204": {
            "description": "No Content",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          }
        }
      },
      "patch": {
        "tags": [
          "Utilities"
        ],
        "summary": "PATCH into the blackhole",
        "description": "Accepts any body up to `MAX_BODY_BYTES`, stores nothing, and replies with one of the standard success outcomes for PATCH, picked at random: 200, 204. Multipart and binary bodies are accepted but never parsed.",
        "operationId": "blackholePatch",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "*/*": {
              "schema": {},
              "example": {
                "anything": "goes"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted into the blackhole",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/BlackholeResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "204": {
            "description": "No Content",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          }
        }
      },
      "delete": {
        "tags": [
          "Utilities"
        ],
        "summary": "DELETE into the blackhole",
        "description": "Accepts any body up to `MAX_BODY_BYTES`, stores nothing, and replies with one of the standard success outcomes for DELETE, picked at random: 200, 202, 204. Multipart and binary bodies are accepted but never parsed.",
        "operationId": "blackholeDelete",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "*/*": {
              "schema": {},
              "example": {
                "anything": "goes"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted into the blackhole",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/BlackholeResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Accepted into the blackhole",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/BlackholeResult"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "204": {
            "description": "No Content",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          }
        }
      }
    },
    "/api/v1/flights": {
      "get": {
        "tags": [
          "Sample data"
        ],
        "summary": "List flights",
        "description": "140 generated flights from New York (JFK) to Los Angeles (LAX) over the next 7 days, with airlines, aircraft, terminals, gates, DST-aware local times, layovers and multi-cabin fares. Generated from a daily seed: stable within a day, new the next.\n\nReturns the whole list unless `page` or `limit` is sent; then one page with `meta.pagination` and `links`.",
        "operationId": "listFlights",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "The list, or one page of it",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "required": [
                        "success",
                        "data",
                        "meta"
                      ],
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "const": true
                        },
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Flight"
                          }
                        },
                        "meta": {
                          "$ref": "#/components/schemas/Meta"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "links": {
                          "$ref": "#/components/schemas/Links"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/api/v1/stocks": {
      "get": {
        "tags": [
          "Sample data"
        ],
        "summary": "List stocks",
        "description": "100 real US tickers with random market data: price, previous close, 1-day change, day and 52-week ranges, volume and market cap. Generated from a daily seed.\n\nReturns the whole list unless `page` or `limit` is sent; then one page with `meta.pagination` and `links`.",
        "operationId": "listStocks",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "The list, or one page of it",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "required": [
                        "success",
                        "data",
                        "meta"
                      ],
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "const": true
                        },
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Stock"
                          }
                        },
                        "meta": {
                          "$ref": "#/components/schemas/Meta"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "links": {
                          "$ref": "#/components/schemas/Links"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/api/v1/users": {
      "get": {
        "tags": [
          "Sample data"
        ],
        "summary": "List users",
        "description": "Small nested user fixtures: profile, contact address with coordinates, company, preferences and stats.\n\nReturns the whole list unless `page` or `limit` is sent; then one page with `meta.pagination` and `links`.",
        "operationId": "listUsers",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "The list, or one page of it",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "required": [
                        "success",
                        "data",
                        "meta"
                      ],
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "const": true
                        },
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        },
                        "meta": {
                          "$ref": "#/components/schemas/Meta"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "links": {
                          "$ref": "#/components/schemas/Links"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/api/v1/products": {
      "get": {
        "tags": [
          "Sample data"
        ],
        "summary": "List products",
        "description": "Product fixtures with category path, pricing and discounts, inventory by warehouse, variants and media.\n\nReturns the whole list unless `page` or `limit` is sent; then one page with `meta.pagination` and `links`.",
        "operationId": "listProducts",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "The list, or one page of it",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "required": [
                        "success",
                        "data",
                        "meta"
                      ],
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "const": true
                        },
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        },
                        "meta": {
                          "$ref": "#/components/schemas/Meta"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "links": {
                          "$ref": "#/components/schemas/Links"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/api/v1/orders": {
      "get": {
        "tags": [
          "Sample data"
        ],
        "summary": "List orders",
        "description": "Order fixtures with customer, line items, totals in cents, payment, shipping address and a status timeline.\n\nReturns the whole list unless `page` or `limit` is sent; then one page with `meta.pagination` and `links`.",
        "operationId": "listOrders",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "The list, or one page of it",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "required": [
                        "success",
                        "data",
                        "meta"
                      ],
                      "properties": {
                        "success": {
                          "type": "boolean",
                          "const": true
                        },
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        },
                        "meta": {
                          "$ref": "#/components/schemas/Meta"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "links": {
                          "$ref": "#/components/schemas/Links"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/whoami": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Describe my request",
        "description": "Returns what the server can see about your request: IP, port, HTTP version, query and headers. `Authorization`, `Proxy-Authorization` and `Cookie` are redacted.",
        "operationId": "whoami",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "Your request",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Whoami"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Health check",
        "operationId": "health",
        "parameters": [
          {
            "$ref": "#/components/parameters/Delay"
          },
          {
            "$ref": "#/components/parameters/Status"
          },
          {
            "$ref": "#/components/parameters/Flaky"
          },
          {
            "$ref": "#/components/parameters/Sequence"
          },
          {
            "$ref": "#/components/parameters/SequenceKey"
          },
          {
            "$ref": "#/components/parameters/SequenceReset"
          },
          {
            "$ref": "#/components/parameters/CustomHeader"
          },
          {
            "$ref": "#/components/parameters/Cors"
          }
        ],
        "responses": {
          "200": {
            "description": "The server is up",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Health"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "data": {
                    "status": "ok",
                    "uptime_seconds": 3605
                  },
                  "meta": {
                    "request_id": "84c310a8-d550-4fb3-ab6b-f19f64c49ab3",
                    "timestamp": "2026-09-27T10:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "503": {
            "$ref": "#/components/responses/DelayCapacityFull"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "deleteToken": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Delete-Token",
        "description": "The `delete_token` returned once by `POST /upload`. Required to replace or delete that mock."
      }
    },
    "parameters": {
      "MockId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "The 22-character ID returned by `POST /upload`. Anything else is rejected with `404` before the server touches disk.",
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{22}$"
        },
        "example": "gqqQumr3tmdItHEfSW7Z6w"
      },
      "Delay": {
        "name": "delay",
        "in": "query",
        "description": "Wait this many milliseconds before responding. Values above `MAX_DELAY_MS` (10 s) are clamped. At most `MAX_CONCURRENT_DELAYS` requests may wait at once.",
        "schema": {
          "type": "integer",
          "minimum": 0
        },
        "example": 2000
      },
      "Status": {
        "name": "status",
        "in": "query",
        "description": "Skip the normal response and return the standard error for this 4xx or 5xx code. With `flaky`, only the failed calls get it.",
        "schema": {
          "type": "integer",
          "minimum": 400,
          "maximum": 599
        },
        "example": 503
      },
      "Flaky": {
        "name": "flaky",
        "in": "query",
        "description": "Fail this fraction of calls (0–1) with `500`, or with `status` if given. Injected failures carry `X-Mock-Injected-Failure: true`.",
        "schema": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "example": 0.2
      },
      "Sequence": {
        "name": "sequence",
        "in": "query",
        "description": "One step per call, then stay on the last: `ok`/`200` runs the route normally, a 4xx/5xx code returns that error. Up to 20 steps. The server counts calls per client IP + method + path + sequence; the client just retries. Responses carry `X-Mock-Sequence: <step>/<total>`.",
        "schema": {
          "type": "string"
        },
        "example": "500,503,ok"
      },
      "SequenceKey": {
        "name": "sequence_key",
        "in": "query",
        "description": "Share one sequence counter across URLs or clients.",
        "schema": {
          "type": "string",
          "maxLength": 100
        },
        "example": "checkout-retry"
      },
      "SequenceReset": {
        "name": "sequence_reset",
        "in": "query",
        "description": "Start the sequence over from step 1 on this call.",
        "schema": {
          "type": "string"
        },
        "allowEmptyValue": true,
        "example": "1"
      },
      "CustomHeader": {
        "name": "header_{Name}",
        "in": "query",
        "description": "Add `{Name}: value` to the response, e.g. `?header_Retry-After=30` or `?header_Cache-Control=no-cache`. Up to 20; printable ASCII. `Set-Cookie`, `Location`, `Content-*`, hop-by-hop, `Access-Control-Allow-Credentials` and the service's own `X-Mock-*` headers are refused.",
        "schema": {
          "type": "string"
        },
        "example": "value"
      },
      "Cors": {
        "name": "cors",
        "in": "query",
        "description": "Set to `off` to drop CORS headers from this request and its preflight, so a browser blocks it — test your app's CORS error handling.",
        "schema": {
          "type": "string",
          "enum": [
            "off"
          ]
        }
      },
      "Page": {
        "name": "page",
        "in": "query",
        "description": "Page number. Only validated when sent; defaults to 1 when only `limit` is sent.",
        "schema": {
          "type": "integer",
          "minimum": 1
        },
        "example": 2
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Items per page (1–100). Only validated when sent; defaults to 10 when only `page` is sent.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        },
        "example": 20
      },
      "IfNoneMatch": {
        "name": "If-None-Match",
        "in": "header",
        "description": "An ETag from an earlier response. If it matches (weak comparison, lists and `*` allowed), the server answers `304` without reading the JSON.",
        "schema": {
          "type": "string"
        },
        "example": "\"3f2aZ9kq…\""
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "description": "Only apply the change if the mock still has this ETag (strong comparison). Otherwise `412`.",
        "schema": {
          "type": "string"
        },
        "example": "\"3f2aZ9kq…\""
      }
    },
    "headers": {
      "XRequestId": {
        "description": "Unique per request; also in `meta.request_id`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "ETag": {
        "description": "Strong ETag: a SHA-256 hash of the stored JSON.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "Writes left in the current bucket for your IP.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "ValidationError": {
        "description": "A query parameter is invalid; every problem is listed in `error.details`",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "success": false,
              "error": {
                "code": "VALIDATION_ERROR",
                "message": "Invalid query parameters",
                "details": [
                  {
                    "field": "delay",
                    "message": "must be a non-negative integer (milliseconds)"
                  }
                ]
              },
              "meta": {
                "request_id": "…",
                "timestamp": "…"
              }
            }
          }
        }
      },
      "InvalidJson": {
        "description": "The body is not valid UTF-8 JSON",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "success": false,
              "error": {
                "code": "INVALID_JSON",
                "message": "Request body must be valid UTF-8 encoded JSON"
              },
              "meta": {
                "request_id": "…",
                "timestamp": "…"
              }
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "The body is larger than `MAX_BODY_BYTES`",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many writes from your IP (30/min by default)",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "DelayCapacityFull": {
        "description": "Too many `?delay` requests are waiting right now",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "MockNotFound": {
        "description": "No such mock, it expired, or the ID is malformed",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "success": false,
              "error": {
                "code": "NOT_FOUND",
                "message": "Mock not found or expired"
              },
              "meta": {
                "request_id": "…",
                "timestamp": "…"
              }
            }
          }
        }
      },
      "MissingToken": {
        "description": "`X-Delete-Token` is missing",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "WrongToken": {
        "description": "`X-Delete-Token` does not match",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "PreconditionFailed": {
        "description": "`If-Match` does not match the current version; nothing changed",
        "headers": {
          "ETag": {
            "$ref": "#/components/headers/ETag"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "NotModified": {
        "description": "`If-None-Match` matched; use your cached copy",
        "headers": {
          "ETag": {
            "$ref": "#/components/headers/ETag"
          }
        }
      }
    },
    "schemas": {
      "Meta": {
        "type": "object",
        "required": [
          "request_id",
          "timestamp"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "Pagination": {
        "type": "object",
        "description": "Only present when `page` or `limit` was sent.",
        "properties": {
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "total_items": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          },
          "has_next": {
            "type": "boolean"
          },
          "has_prev": {
            "type": "boolean"
          }
        }
      },
      "Links": {
        "type": "object",
        "description": "Only present when paginating.",
        "properties": {
          "self": {
            "type": "string"
          },
          "next": {
            "type": [
              "string",
              "null"
            ]
          },
          "prev": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ErrorDetail": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": [
          "success",
          "error",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "examples": [
                  "NOT_FOUND",
                  "TOO_MANY_REQUESTS"
                ]
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ErrorDetail"
                }
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/Meta"
          }
        }
      },
      "UploadResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "examples": [
              "gqqQumr3tmdItHEfSW7Z6w"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "delete_token": {
            "type": "string",
            "description": "Returned only once"
          },
          "etag": {
            "type": "string"
          }
        }
      },
      "UpdateResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "size_bytes": {
            "type": "integer"
          },
          "etag": {
            "type": "string"
          }
        }
      },
      "BlackholeResult": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "examples": [
              "Resource created successfully"
            ]
          },
          "method": {
            "type": "string"
          },
          "received_bytes": {
            "type": "integer"
          }
        }
      },
      "EchoResult": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "query": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          "http_version": {
            "type": "string"
          },
          "ip": {
            "type": "string"
          },
          "secure": {
            "type": "boolean"
          },
          "headers": {
            "type": "object",
            "description": "Original casing; repeated headers become arrays."
          },
          "body": {
            "type": "object",
            "properties": {
              "size_bytes": {
                "type": "integer"
              },
              "content_type": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "encoding": {
                "type": "string",
                "enum": [
                  "empty",
                  "utf8",
                  "base64",
                  "multipart"
                ]
              },
              "text": {
                "type": "string",
                "description": "Exactly what arrived (utf8)"
              },
              "json": {
                "description": "Parsed JSON, when the text parses"
              },
              "base64": {
                "type": "string"
              },
              "parts": {
                "type": "array",
                "description": "For multipart/form-data",
                "items": {
                  "type": "object",
                  "properties": {
                    "index": {
                      "type": "integer"
                    },
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "field",
                        "file"
                      ]
                    },
                    "value": {
                      "type": "string"
                    },
                    "filename": {
                      "type": "string"
                    },
                    "content_type": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "size_bytes": {
                      "type": "integer"
                    },
                    "sha256": {
                      "type": "string"
                    }
                  }
                }
              },
              "multipart_error": {
                "type": "string",
                "description": "Why a multipart body could not be parsed"
              }
            }
          }
        }
      },
      "Whoami": {
        "type": "object",
        "properties": {
          "ip": {
            "type": "string"
          },
          "port": {
            "type": "integer"
          },
          "method": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "query": {
            "type": "object"
          },
          "http_version": {
            "type": "string"
          },
          "secure": {
            "type": "boolean"
          },
          "user_agent": {
            "type": [
              "string",
              "null"
            ]
          },
          "headers": {
            "type": "object"
          }
        }
      },
      "Health": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "const": "ok"
          },
          "uptime_seconds": {
            "type": "integer"
          }
        }
      },
      "Money": {
        "type": "object",
        "description": "Amount in cents",
        "properties": {
          "amount": {
            "type": "integer",
            "examples": [
              21900
            ]
          },
          "currency": {
            "type": "string",
            "examples": [
              "USD"
            ]
          }
        }
      },
      "Flight": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "examples": [
              "flt_20260928_DL1234"
            ]
          },
          "flight_number": {
            "type": "string",
            "examples": [
              "DL 1234"
            ]
          },
          "airline": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "aircraft": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "origin": {
            "$ref": "#/components/schemas/Airport"
          },
          "destination": {
            "$ref": "#/components/schemas/Airport"
          },
          "departure": {
            "$ref": "#/components/schemas/FlightTime"
          },
          "arrival": {
            "$ref": "#/components/schemas/FlightTime"
          },
          "duration_minutes": {
            "type": "integer"
          },
          "stops": {
            "type": "integer",
            "enum": [
              0,
              1
            ]
          },
          "layovers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "airport": {
                  "type": "object"
                },
                "duration_minutes": {
                  "type": "integer"
                }
              }
            }
          },
          "fares": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Fare"
            }
          },
          "lowest_price": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "examples": [
              "scheduled"
            ]
          }
        }
      },
      "Airport": {
        "type": "object",
        "properties": {
          "iata": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "terminal": {
            "type": "string"
          }
        }
      },
      "FlightTime": {
        "type": "object",
        "properties": {
          "scheduled_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC"
          },
          "local_time": {
            "type": "string",
            "description": "Airport local time with its DST-aware offset"
          },
          "gate": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Fare": {
        "type": "object",
        "properties": {
          "cabin": {
            "type": "string",
            "enum": [
              "economy",
              "premium_economy",
              "business"
            ]
          },
          "fare_class": {
            "type": "string"
          },
          "price": {
            "$ref": "#/components/schemas/Money"
          },
          "seats_left": {
            "type": [
              "integer",
              "null"
            ],
            "description": "null means plenty, 0 means sold out"
          },
          "refundable": {
            "type": "boolean"
          },
          "changeable": {
            "type": "boolean"
          },
          "baggage": {
            "type": "object",
            "properties": {
              "carry_on": {
                "type": "integer"
              },
              "checked": {
                "type": "integer"
              }
            }
          }
        }
      },
      "Stock": {
        "type": "object",
        "properties": {
          "ticker": {
            "type": "string",
            "examples": [
              "AAPL"
            ]
          },
          "name": {
            "type": "string"
          },
          "exchange": {
            "type": "string",
            "enum": [
              "NASDAQ",
              "NYSE"
            ]
          },
          "sector": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "price": {
            "type": "number"
          },
          "previous_close": {
            "type": "number"
          },
          "change": {
            "type": "number"
          },
          "change_percent": {
            "type": "number"
          },
          "direction": {
            "type": "string",
            "enum": [
              "up",
              "down",
              "flat"
            ]
          },
          "day": {
            "type": "object",
            "properties": {
              "open": {
                "type": "number"
              },
              "high": {
                "type": "number"
              },
              "low": {
                "type": "number"
              }
            }
          },
          "week_52": {
            "type": "object",
            "properties": {
              "high": {
                "type": "number"
              },
              "low": {
                "type": "number"
              }
            }
          },
          "volume": {
            "type": "integer"
          },
          "market_cap": {
            "type": "integer"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}
