{
  "openapi": "3.1.0",
  "info": {
    "title": "Qpro+ Label and Document API",
    "version": "2026-09-29",
    "summary": "Render saved label and document templates with runtime data.",
    "description": "Templates are designed and stored in the Qpro+ canvas. Send a template name, copy count and field values; get markup JSON, ZPL, PDF or SVG back, or print through PrintNode. Every render counts toward the plan's print allowance.",
    "contact": {
      "name": "Quando Solutions LLC",
      "url": "https://quandopro.com/contact.html"
    }
  },
  "externalDocs": {
    "description": "API reference",
    "url": "https://quandopro.com/api-reference.html"
  },
  "servers": [
    {
      "url": "https://api.beta.quandosol.com/api",
      "description": "Sandbox. Production uses the base URL issued with production credentials."
    }
  ],
  "security": [
    {
      "apiKey": [],
      "apiSecret": []
    }
  ],
  "tags": [
    {
      "name": "Render and print"
    }
  ],
  "paths": {
    "/custom-labels/fetch-markups": {
      "post": {
        "operationId": "fetchMarkups",
        "summary": "01 Fetch Markups",
        "description": "Qpro+ loads the template you name, fills every field from apiData, and returns the resolved label as markup: the stage size and every element with its final value. Nothing is rendered to a file and nothing prints. Use it to confirm your field values resolve before you wire up any output, to feed a renderer of your own, or to inspect exactly what a template contains.",
        "tags": [
          "Render and print"
        ],
        "externalDocs": {
          "url": "https://quandopro.com/api-reference.html#fetch-markups"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LabelRequest"
              },
              "example": {
                "label_name": "FG-PALLET-4x6",
                "amount": 1,
                "apiData": {
                  "lot_number": "L25-8814",
                  "pallet_id": "PLT-4471",
                  "piece_qty": "48 CS",
                  "customer_code": "NORTHFIELD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Markup"
                  }
                },
                "example": [
                  {
                    "stage": {
                      "width": 4,
                      "height": 6,
                      "unit": "in",
                      "background": "#ffffff"
                    },
                    "elements": [
                      {
                        "type": "text",
                        "text": "L25-8814",
                        "x": 20,
                        "y": 15
                      },
                      {
                        "type": "barcode",
                        "format": "code128",
                        "text": "PLT-4471"
                      },
                      {
                        "type": "image",
                        "url": "https://…",
                        "x": 10,
                        "y": 80
                      }
                    ]
                  }
                ]
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No template with that label_name.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Missing or invalid parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min per key by default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Render failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/custom-labels/print": {
      "post": {
        "operationId": "printMarkups",
        "summary": "02 Print Markups",
        "description": "The Qpro+ SDK calls this route, receives the same markup as Fetch Markups, draws the label to a canvas inside a hidden iframe, and triggers the browser's native print dialog. Choosing “Save as PDF” in that dialog produces a PDF file. This is the one method designed to run in a browser. It needs no PrintNode account and no print server. Note: Because this method runs in the browser, the key and secret passed to setConfig are readable by anyone who can open the page. Use it on internal, signed-in pages, and use a server-side method anywhere the page is public.",
        "tags": [
          "Render and print"
        ],
        "externalDocs": {
          "url": "https://quandopro.com/api-reference.html#print"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LabelRequest"
              },
              "example": {
                "label_name": "FG-PALLET-4x6",
                "amount": 1,
                "apiData": {
                  "lot_number": "L25-8814",
                  "pallet_id": "PLT-4471",
                  "piece_qty": "48 CS",
                  "customer_code": "NORTHFIELD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Markup"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No template with that label_name.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Missing or invalid parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min per key by default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Render failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/custom-labels/print-node": {
      "post": {
        "operationId": "printNodeZpl",
        "summary": "03 PrintNode ZPL",
        "description": "Qpro+ renders the label server-side, converts it to ZPL, and delivers it through PrintNode to a Zebra or other ZPL-compatible thermal printer. No browser is involved, which makes this the method for background and automated printing. PrintNode is only the courier. The ZPL is produced by Qpro+, and it asks PrintNode for the printer's resolution so the output matches the hardware.",
        "tags": [
          "Render and print"
        ],
        "externalDocs": {
          "url": "https://quandopro.com/api-reference.html#print-node"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrintNodeRequest"
              },
              "example": {
                "label_name": "FG-PALLET-4x6",
                "amount": 1,
                "printer_id": 75208784,
                "apiData": {
                  "lot_number": "L25-8814",
                  "pallet_id": "PLT-4471",
                  "piece_qty": "48 CS",
                  "customer_code": "NORTHFIELD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrintNodeResult"
                },
                "example": {
                  "status": "sent_to_printer",
                  "printer_dpi": 203
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No template with that label_name.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Missing or invalid parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min per key by default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Render failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/custom-labels/print-node-pdf": {
      "post": {
        "operationId": "printNodePdf",
        "summary": "04 PrintNode PDF",
        "description": "Qpro+ builds a vector PDF of the label server-side and delivers it through PrintNode to any printer that accepts PDF. It gives the sharpest output for labels and documents with graphics, and it works on standard office and laser printers. Note: A PDF cannot carry an RFID tag payload, so a template with an RFID element is refused with 422. Print RFID labels with PrintNode ZPL or Render ZPL.",
        "tags": [
          "Render and print"
        ],
        "externalDocs": {
          "url": "https://quandopro.com/api-reference.html#print-node-pdf"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrintNodeRequest"
              },
              "example": {
                "label_name": "FG-PALLET-4x6",
                "amount": 1,
                "printer_id": 75236019,
                "apiData": {
                  "lot_number": "L25-8814",
                  "pallet_id": "PLT-4471",
                  "piece_qty": "48 CS",
                  "customer_code": "NORTHFIELD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrintNodeResult"
                },
                "example": {
                  "status": "sent_to_printer_png"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No template with that label_name.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Missing or invalid parameters, or the template contains an RFID element.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min per key by default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Render failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/custom-labels/export-svg": {
      "post": {
        "operationId": "exportSvg",
        "summary": "05 Export SVG",
        "description": "Qpro+ resolves the template, renders one SVG per copy on the server, stores the files, and returns a URL for each. The files expire after the period given in ttl_hours, 24 hours today, so download what you need to keep. Note: Anyone holding a file URL can open it until it expires. If a label carries personal data, keep the URLs server-side and hand your users your own copy.",
        "tags": [
          "Render and print"
        ],
        "externalDocs": {
          "url": "https://quandopro.com/api-reference.html#export-svg"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LabelRequest"
              },
              "example": {
                "label_name": "FG-PALLET-4x6",
                "amount": 1,
                "apiData": {
                  "lot_number": "L25-8814",
                  "pallet_id": "PLT-4471",
                  "piece_qty": "48 CS",
                  "customer_code": "NORTHFIELD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SvgExport"
                },
                "example": {
                  "status": "svg_exported",
                  "ttl_hours": 24,
                  "expires_at": "2026-10-01T12:00:00+00:00",
                  "files": [
                    {
                      "url": "https://api.beta.quandosol.com/storage/custom-label-svgs/2026/09/30/fg-pallet-4x6-uuid.svg",
                      "path": "custom-label-svgs/2026/09/30/fg-pallet-4x6-uuid.svg",
                      "expires_at": "2026-10-01T12:00:00+00:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No template with that label_name.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Missing or invalid parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min per key by default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Render failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/custom-labels/render-zpl": {
      "post": {
        "operationId": "renderZpl",
        "summary": "06 Render ZPL",
        "description": "The same ZPL as PrintNode ZPL, handed back to you instead of sent to a printer. Use it when you already relay print jobs to your own printers: a raw socket on port 9100, a CUPS raw queue, or an existing print relay. No PrintNode account is involved. There is no printer to ask for its size here, so tell Qpro+ with dpi and max_width_dots. Wrong values don't raise an error; they print a label that is too wide or too small.",
        "tags": [
          "Render and print"
        ],
        "externalDocs": {
          "url": "https://quandopro.com/api-reference.html#render-zpl"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenderZplRequest"
              },
              "example": {
                "label_name": "FG-PALLET-4x6",
                "amount": 1,
                "dpi": 300,
                "max_width_dots": 1248,
                "apiData": {
                  "lot_number": "L25-8814",
                  "pallet_id": "PLT-4471",
                  "piece_qty": "48 CS",
                  "customer_code": "NORTHFIELD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZplResult"
                },
                "example": {
                  "dpi": 300,
                  "max_width_dots": 1248,
                  "count": 1,
                  "labels": [
                    "^XA\n^PW1248\n^LL1800\n^LH0,0\n^FO0,0\n^GFA,…^FS\n^XZ\n"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Missing or invalid parameters, or unknown label_name (this route returns 422, not 404).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min per key by default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Render failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/custom-labels/render-pdf": {
      "post": {
        "operationId": "renderPdf",
        "summary": "07 Render PDF",
        "description": "The same vector PDF as PrintNode PDF, returned base64-encoded in the JSON response instead of sent to a printer. The file is built entirely inside Qpro+, with no headless browser and no outside service in the path, so you can print it, archive it, attach it to a shipment, or email it. Note: RFID templates are refused with 422 and the message “RFID labels must be rendered as ZPL. PDF cannot encode RFID tags.” Use Render ZPL for those.",
        "tags": [
          "Render and print"
        ],
        "externalDocs": {
          "url": "https://quandopro.com/api-reference.html#render-pdf"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LabelRequest"
              },
              "example": {
                "label_name": "FG-PALLET-4x6",
                "amount": 1,
                "apiData": {
                  "lot_number": "L25-8814",
                  "pallet_id": "PLT-4471",
                  "piece_qty": "48 CS",
                  "customer_code": "NORTHFIELD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfResult"
                },
                "example": {
                  "mime": "application/pdf",
                  "encoding": "base64",
                  "count": 1,
                  "labels": [
                    "JVBERi0xLjcKJeLjz9M…"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Missing or invalid parameters, or unknown label_name (this route returns 422, not 404). Also returned for RFID templates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (60/min per key by default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Render failure.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "LabelRequest": {
        "type": "object",
        "required": [
          "label_name",
          "amount",
          "apiData"
        ],
        "properties": {
          "label_name": {
            "type": "string",
            "description": "Exact template name in your account. Case-sensitive.",
            "examples": [
              "FG-PALLET-4x6"
            ]
          },
          "amount": {
            "type": "integer",
            "minimum": 1,
            "description": "Copies to produce. Each copy is returned or printed separately.",
            "examples": [
              1
            ]
          },
          "apiData": {
            "type": "object",
            "description": "Field values keyed by the template's mapped field names. Case-sensitive keys.",
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "lot_number": "L25-8814",
                "pallet_id": "PLT-4471",
                "piece_qty": "48 CS",
                "customer_code": "NORTHFIELD"
              }
            ]
          }
        }
      },
      "PrintNodeRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/LabelRequest"
          },
          {
            "type": "object",
            "required": [
              "printer_id"
            ],
            "properties": {
              "printer_id": {
                "type": "integer",
                "description": "PrintNode printer ID."
              }
            }
          }
        ]
      },
      "RenderZplRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/LabelRequest"
          },
          {
            "type": "object",
            "properties": {
              "dpi": {
                "type": "integer",
                "minimum": 100,
                "maximum": 1200,
                "default": 203
              },
              "max_width_dots": {
                "type": "integer",
                "minimum": 100,
                "maximum": 10000,
                "default": 832
              }
            }
          }
        ]
      },
      "Markup": {
        "type": "object",
        "properties": {
          "stage": {
            "type": "object",
            "properties": {
              "width": {
                "type": "number"
              },
              "height": {
                "type": "number"
              },
              "unit": {
                "type": "string"
              },
              "background": {
                "type": "string"
              }
            }
          },
          "elements": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "PrintNodeResult": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          },
          "printer_dpi": {
            "type": "integer"
          }
        }
      },
      "SvgExport": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          },
          "ttl_hours": {
            "type": "integer"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "path": {
                  "type": "string"
                },
                "expires_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "ZplResult": {
        "type": "object",
        "properties": {
          "dpi": {
            "type": "integer"
          },
          "max_width_dots": {
            "type": "integer"
          },
          "count": {
            "type": "integer"
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "PdfResult": {
        "type": "object",
        "properties": {
          "mime": {
            "type": "string",
            "const": "application/pdf"
          },
          "encoding": {
            "type": "string",
            "const": "base64"
          },
          "count": {
            "type": "integer"
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string",
              "contentEncoding": "base64"
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "description": "Error body. Includes a human-readable message; exact shape not formally specified.",
        "additionalProperties": true
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-KEY"
      },
      "apiSecret": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-SECRET"
      }
    }
  }
}