{
  "openapi": "3.0.4",
  "info": {
    "title": "TestingAPIs: products and echo",
    "version": "v1",
    "description": "Part of the live OpenAPI document at https://api.testingapis.com, cut down to the free endpoints used by https://testingapis.com/blog/arazzo-1-1."
  },
  "servers": [
    {
      "url": "https://api.testingapis.com"
    }
  ],
  "paths": {
    "/api/Products": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "List products with filtering, sorting, search and pagination.",
        "description": "Common filters: `category`, `inStock`. Any other property name also works as an exact, case-insensitive filter.\nPaging and sorting: `limit` (1-100), `page` (1-based, needs `limit`), `offset`, `sort` (property name),\n`order` (`asc` or `desc`) and `q` (search across title, name, body, description and text fields).\nTotals are returned in the X-Total-Count, X-Page, X-Per-Page and X-Total-Pages headers.",
        "operationId": "Products_GetAll",
        "responses": {
          "200": {
            "description": "The matching products."
          },
          "500": {
            "description": "Unexpected server error."
          }
        }
      },
      "post": {
        "tags": [
          "Products"
        ],
        "summary": "Create a product.",
        "operationId": "Products_Create",
        "requestBody": {
          "description": "The new product. Any client-supplied ID is replaced.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Product"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "201": {
            "description": "Created; returns { message, data } with the generated ID."
          },
          "400": {
            "description": "title is missing."
          },
          "500": {
            "description": "Unexpected server error."
          }
        }
      }
    },
    "/api/Products/{id}": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get a product by ID.",
        "operationId": "Products_GetById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Product ID.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The product."
          },
          "404": {
            "description": "The product does not exist."
          },
          "500": {
            "description": "Unexpected server error."
          }
        }
      },
      "put": {
        "tags": [
          "Products"
        ],
        "summary": "Update a product.",
        "description": "Replaces title, price, description, category, image and inStock; rating is kept when omitted.",
        "operationId": "Products_Update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Product ID.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "The new field values.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Product"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated; returns { message, data }."
          },
          "404": {
            "description": "The product does not exist."
          },
          "500": {
            "description": "Unexpected server error."
          }
        }
      },
      "delete": {
        "tags": [
          "Products"
        ],
        "summary": "Delete a product.",
        "operationId": "Products_Delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Product ID.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted."
          },
          "404": {
            "description": "The product does not exist."
          },
          "500": {
            "description": "Unexpected server error."
          }
        }
      }
    },
    "/api/echo": {
      "post": {
        "tags": [
          "Echo"
        ],
        "summary": "Echoes back everything the server received: method, URL, query, headers, cookies, body and client info.",
        "description": "Accepts GET, POST, PUT, PATCH, DELETE, HEAD and OPTIONS on `/api/echo` and on any sub-path\n(`/api/echo/{**path}`); the sub-path is returned as `subPath`.\nUp to 1MB of body is echoed (UTF-8 text, or base64 for binary); larger bodies are counted in\n`contentLength` and flagged with `bodyTruncated`. JSON bodies are also returned parsed in `json`\n(or `jsonError` when malformed), and form bodies as `form` fields plus `files` metadata.\nExample: `POST /api/echo/orders/7?tag=a&tag=b` with a JSON body.",
        "operationId": "Echo_Echo_POST",
        "requestBody": {
          "description": "Any body; it is echoed back.",
          "content": {
            "application/json": {
              "schema": {
                "description": "Any JSON value"
              },
              "example": {
                "hello": "world",
                "n": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The request as the server saw it (HEAD responses carry headers only)."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Product": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "price": {
            "type": "number",
            "format": "double"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "nullable": true
          },
          "image": {
            "type": "string",
            "nullable": true
          },
          "rating": {
            "$ref": "#/components/schemas/Rating"
          },
          "inStock": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "Rating": {
        "type": "object",
        "properties": {
          "rate": {
            "type": "number",
            "format": "double"
          },
          "count": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      }
    }
  }
}
