{
  "openapi": "3.1.0",
  "info": {
    "title": "QuickChart API",
    "version": "1.0.0",
    "description": "Generate Chart.js chart images, QR codes, barcodes, and machine-readable validation results.",
    "contact": {
      "name": "QuickChart Support",
      "email": "support@quickchart.io",
      "url": "https://quickchart.io/contact/"
    }
  },
  "servers": [
    {
      "url": "https://quickchart.io"
    }
  ],
  "tags": [
    { "name": "Charts" },
    { "name": "QR codes" },
    { "name": "Barcodes" },
    { "name": "Validation" },
    { "name": "Discovery" }
  ],
  "paths": {
    "/openapi.json": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getOpenApiSpec",
        "summary": "Fetch the QuickChart OpenAPI description.",
        "responses": {
          "200": {
            "description": "OpenAPI JSON document.",
            "content": {
              "application/json": {
                "schema": { "type": "object" }
              }
            }
          }
        }
      }
    },
    "/chart": {
      "get": {
        "tags": ["Charts"],
        "operationId": "getChart",
        "summary": "Generate a chart image from query parameters.",
        "parameters": [
          {
            "name": "chart",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Chart.js configuration object as JSON or Javascript."
          },
          {
            "name": "c",
            "in": "query",
            "schema": { "type": "string" },
            "description": "Alias for chart."
          },
          { "name": "width", "in": "query", "schema": { "type": "integer", "default": 500 } },
          { "name": "height", "in": "query", "schema": { "type": "integer", "default": 300 } },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["png", "jpg", "jpeg", "webp", "svg", "pdf", "base64"]
            }
          },
          { "name": "backgroundColor", "in": "query", "schema": { "type": "string" } },
          {
            "name": "version",
            "in": "query",
            "schema": { "type": "string", "enum": ["2", "3", "4"] }
          },
          {
            "name": "encoding",
            "in": "query",
            "schema": { "type": "string", "enum": ["url", "base64"] }
          },
          { "name": "key", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/ImageResponse" },
          "400": { "$ref": "#/components/responses/JsonError" }
        }
      },
      "post": {
        "tags": ["Charts"],
        "operationId": "postChart",
        "summary": "Generate a chart image from a JSON request body.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ChartRequest" }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/ImageResponse" },
          "400": { "$ref": "#/components/responses/JsonError" }
        }
      }
    },
    "/api/validate-chart": {
      "post": {
        "tags": ["Validation"],
        "operationId": "validateChart",
        "summary": "Validate a chart request and return JSON instead of an image.",
        "description": "Runs the chart configuration through the renderer and discards the image bytes. Use this before retrying or saving generated chart configs.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ChartRequest" }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/ValidationResponse" },
          "400": { "$ref": "#/components/responses/ValidationResponse" },
          "403": { "$ref": "#/components/responses/ValidationResponse" }
        }
      }
    },
    "/qr": {
      "get": {
        "tags": ["QR codes"],
        "operationId": "getQr",
        "summary": "Generate a QR code from query parameters.",
        "parameters": [
          { "name": "text", "in": "query", "required": true, "schema": { "type": "string" } },
          {
            "name": "format",
            "in": "query",
            "schema": { "type": "string", "enum": ["png", "svg", "jpg", "jpeg", "base64"] }
          },
          { "name": "size", "in": "query", "schema": { "type": "integer", "default": 150 } },
          { "name": "margin", "in": "query", "schema": { "type": "integer", "default": 4 } },
          {
            "name": "ecLevel",
            "in": "query",
            "schema": { "type": "string", "enum": ["L", "M", "Q", "H"] }
          },
          { "name": "dark", "in": "query", "schema": { "type": "string" } },
          { "name": "light", "in": "query", "schema": { "type": "string" } },
          { "name": "key", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/ImageResponse" },
          "400": { "$ref": "#/components/responses/JsonError" }
        }
      },
      "post": {
        "tags": ["QR codes"],
        "operationId": "postQr",
        "summary": "Generate a QR code from a JSON request body.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/QrRequest" }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/ImageResponse" },
          "400": { "$ref": "#/components/responses/JsonError" },
          "403": { "$ref": "#/components/responses/JsonError" }
        }
      }
    },
    "/api/validate-qr": {
      "post": {
        "tags": ["Validation"],
        "operationId": "validateQr",
        "summary": "Validate a QR code request and return JSON instead of an image.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/QrRequest" }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/ValidationResponse" },
          "400": { "$ref": "#/components/responses/ValidationResponse" },
          "403": { "$ref": "#/components/responses/ValidationResponse" }
        }
      }
    },
    "/qr/batch": {
      "post": {
        "tags": ["QR codes"],
        "operationId": "postQrBatch",
        "summary": "Generate many QR codes and return a ZIP archive.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 1000,
                    "items": { "$ref": "#/components/schemas/QrRequest" }
                  },
                  {
                    "type": "object",
                    "required": ["qrCodes"],
                    "properties": {
                      "qrCodes": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 1000,
                        "items": { "$ref": "#/components/schemas/QrRequest" }
                      },
                      "zipFilename": { "type": "string", "default": "qr-codes.zip" }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ZIP archive containing one generated QR image per request item.",
            "content": {
              "application/zip": {
                "schema": { "type": "string", "format": "binary" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/JsonError" },
          "403": { "$ref": "#/components/responses/JsonError" }
        }
      }
    },
    "/barcode": {
      "post": {
        "tags": ["Barcodes"],
        "operationId": "postBarcode",
        "summary": "Generate a barcode from a JSON request body.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["type", "text"],
                "properties": {
                  "type": { "type": "string", "description": "Barcode type, such as code128 or ean13." },
                  "text": { "type": "string" },
                  "data": { "type": "string", "description": "Alias for text." },
                  "format": { "type": "string", "enum": ["png", "svg"], "default": "png" },
                  "width": { "type": "integer" },
                  "height": { "type": "integer" },
                  "scale": { "type": "integer", "default": 1 },
                  "includeText": { "type": "boolean" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/ImageResponse" },
          "400": { "$ref": "#/components/responses/JsonError" }
        }
      }
    },
    "/natural/config": {
      "post": {
        "tags": ["Charts"],
        "operationId": "postNaturalChartConfig",
        "summary": "Generate an agent-friendly chart config from natural language.",
        "description": "Returns the generated Chart.js config, a saved chart URL, and an editor URL instead of only returning image bytes.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["description"],
                "properties": {
                  "description": { "type": "string", "maxLength": 512 },
                  "width": { "type": "integer", "default": 500 },
                  "height": { "type": "integer", "default": 300 },
                  "backgroundColor": { "type": "string", "default": "transparent" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated chart configuration and URLs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "description": { "type": "string" },
                    "chart": { "type": "string" },
                    "chartUrl": { "type": "string" },
                    "chartMakerUrl": { "type": "string" },
                    "warnings": { "type": "array", "items": { "type": "string" } }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKeyQuery": { "type": "apiKey", "in": "query", "name": "key" },
      "apiKeyBearer": { "type": "http", "scheme": "bearer" }
    },
    "schemas": {
      "ChartRequest": {
        "type": "object",
        "required": ["chart"],
        "properties": {
          "chart": {
            "oneOf": [{ "type": "object" }, { "type": "string" }],
            "description": "Chart.js configuration object, or a Javascript object string."
          },
          "c": {
            "oneOf": [{ "type": "object" }, { "type": "string" }],
            "description": "Alias for chart."
          },
          "width": { "type": "integer", "minimum": 1, "maximum": 3000, "default": 500 },
          "w": { "type": "integer", "minimum": 1, "maximum": 3000, "description": "Alias for width." },
          "height": { "type": "integer", "minimum": 1, "maximum": 3000, "default": 300 },
          "h": { "type": "integer", "minimum": 1, "maximum": 3000, "description": "Alias for height." },
          "devicePixelRatio": { "type": "number", "default": 2 },
          "backgroundColor": { "type": "string", "default": "transparent" },
          "bkg": { "type": "string", "description": "Alias for backgroundColor." },
          "version": { "type": "string", "enum": ["2", "3", "4"], "default": "2" },
          "v": { "type": "string", "enum": ["2", "3", "4"], "description": "Alias for version." },
          "format": {
            "type": "string",
            "enum": ["png", "jpg", "jpeg", "webp", "svg", "pdf", "base64"],
            "default": "png"
          },
          "f": {
            "type": "string",
            "enum": ["png", "jpg", "jpeg", "webp", "svg", "pdf", "base64"],
            "description": "Alias for format."
          },
          "encoding": { "type": "string", "enum": ["url", "base64"], "default": "url" },
          "templateOverrides": {
            "oneOf": [{ "type": "object" }, { "type": "string" }],
            "description": "Saved-template override values."
          },
          "key": {
            "type": "string",
            "description": "QuickChart API key. Prefer the Authorization header for new integrations."
          }
        }
      },
      "QrRequest": {
        "type": "object",
        "required": ["text"],
        "properties": {
          "text": { "type": "string", "description": "Text, URL, or payload to encode in the QR code." },
          "format": { "type": "string", "enum": ["png", "svg", "jpg", "jpeg", "base64"], "default": "png" },
          "size": { "type": "integer", "minimum": 1, "maximum": 3000, "default": 150 },
          "margin": { "type": "integer", "default": 4 },
          "ecLevel": { "type": "string", "enum": ["L", "M", "Q", "H"] },
          "dark": { "type": "string", "default": "000000" },
          "light": { "type": "string", "default": "ffffff" },
          "finderColor": { "type": "string" },
          "dotStyle": { "type": "string", "enum": ["square", "dot", "dots", "round", "circle", "rounded"] },
          "finderStyle": { "type": "string", "enum": ["square", "rounded", "circle", "dot", "dots"] },
          "finderDotStyle": { "type": "string", "enum": ["square", "rounded", "dot", "dots", "circle"] },
          "centerImageUrl": { "type": "string" },
          "centerImageSizeRatio": { "type": "number", "minimum": 0, "maximum": 1, "default": 0.3 },
          "centerImageWidth": { "type": "integer" },
          "centerImageHeight": { "type": "integer" },
          "caption": { "type": "string" },
          "captionFontFamily": { "type": "string" },
          "captionFontSize": { "type": "integer" },
          "captionFontColor": { "type": "string" },
          "filename": { "type": "string" },
          "key": {
            "type": "string",
            "description": "QuickChart API key. Prefer the Authorization header for new integrations."
          }
        }
      }
    },
    "responses": {
      "ImageResponse": {
        "description": "Generated image response.",
        "content": {
          "image/png": { "schema": { "type": "string", "format": "binary" } },
          "image/jpeg": { "schema": { "type": "string", "format": "binary" } },
          "image/svg+xml": { "schema": { "type": "string", "format": "binary" } },
          "image/webp": { "schema": { "type": "string", "format": "binary" } },
          "application/pdf": { "schema": { "type": "string", "format": "binary" } },
          "text/plain": {
            "schema": { "type": "string", "description": "Base64-encoded image when format=base64." }
          }
        }
      },
      "ValidationResponse": {
        "description": "Structured validation result.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": ["success", "errors", "warnings", "normalized"],
              "properties": {
                "success": { "type": "boolean" },
                "errors": { "type": "array", "items": { "type": "string" } },
                "warnings": { "type": "array", "items": { "type": "string" } },
                "normalized": { "type": "object" },
                "renderCheck": {
                  "type": "object",
                  "properties": {
                    "contentType": { "type": "string" },
                    "bytes": { "type": "integer" }
                  }
                }
              }
            }
          }
        }
      },
      "JsonError": {
        "description": "Structured error response.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": ["success", "error"],
              "properties": {
                "success": { "type": "boolean", "enum": [false] },
                "error": { "type": "string" },
                "errors": { "type": "array", "items": { "type": "string" } }
              }
            }
          }
        }
      }
    }
  }
}
