{
  "openapi": "3.1.0",
  "info": {
    "title": "LuckPanda public API (free tools)",
    "version": "1.0.0",
    "summary": "Prefill links, branded PDFs, document rules and calculators. No authentication.",
    "description": "Endpoints behind LuckPanda's free tool pages, for AI agents and scripts. No account or key. Rate-limited per network (429 RATE_LIMITED with a message). Agents never issue, number, send or take payment: those need a person signed in to LuckPanda (https://luckpanda.app/signin). Guide: https://luckpanda.app/agents.md. MCP: https://luckpanda.app/mcp/public.",
    "contact": {
      "url": "https://luckpanda.app/agents"
    }
  },
  "servers": [
    {
      "url": "https://luckpanda.app"
    }
  ],
  "externalDocs": {
    "url": "https://luckpanda.app/agents.md",
    "description": "LuckPanda for AI agents"
  },
  "tags": [
    {
      "name": "documents"
    },
    {
      "name": "calculators"
    }
  ],
  "paths": {
    "/api/public/drafts": {
      "post": {
        "operationId": "createDocumentLink",
        "tags": [
          "documents"
        ],
        "summary": "Create a short link that opens a prefilled document",
        "description": "Validates the document leniently (invalid parts are left out and listed in `ignored`) and stores it behind a short link that opens the editor filled in for 7 days. Also returns totals with tax, and the required fields still missing. 60 an hour and 300 a day per network.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Link created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkResult"
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/Problem"
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "429": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/d/{id}": {
      "get": {
        "operationId": "openDocumentLink",
        "tags": [
          "documents"
        ],
        "summary": "Open a short link (redirects to the tool page with the document)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-hj-km-np-z2-9]{12}$"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to the tool page that shows the document"
          },
          "404": {
            "description": "Unknown or expired link (HTML page)"
          }
        }
      }
    },
    "/api/public/pdf": {
      "post": {
        "operationId": "createDocumentPdf",
        "tags": [
          "documents"
        ],
        "summary": "Render the free branded PDF of a document",
        "description": "The document is validated strictly, like a saved guest draft (kind, currency, country_code, locale, seller, buyer, issue_date and lines are required). Returns the PDF with a LuckPanda footer and a verification code. Limits: 40 an hour and 150 a day per network, 20 an hour per browser cookie.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "doc"
                ],
                "properties": {
                  "doc": {
                    "$ref": "#/components/schemas/StrictDocument"
                  },
                  "guest_draft_id": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The PDF",
            "headers": {
              "x-lp-verify-url": {
                "schema": {
                  "type": "string"
                },
                "description": "Public verification page of this PDF"
              },
              "x-lp-verify-code": {
                "schema": {
                  "type": "string"
                }
              },
              "x-lp-pdf-pages": {
                "schema": {
                  "type": "integer"
                }
              },
              "x-lp-pdf-variant": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "branded"
                  ]
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Problem"
          },
          "413": {
            "$ref": "#/components/responses/Problem"
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "429": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/api/public/rules": {
      "get": {
        "operationId": "getDocumentRules",
        "tags": [
          "documents"
        ],
        "summary": "Fields and tax rules for a document type and country",
        "parameters": [
          {
            "name": "document_type",
            "in": "query",
            "required": true,
            "description": "invoice | quote | proforma | credit_note | receipt",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": true,
            "description": "ISO alpha-2 of the seller",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rules",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/api/public/tools": {
      "get": {
        "operationId": "listTools",
        "tags": [
          "documents"
        ],
        "summary": "The free document pages and calculators",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Search text",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "document_type",
            "in": "query",
            "required": false,
            "description": "Filter by type",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "ISO alpha-2",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tool list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/calc/gst": {
      "get": {
        "operationId": "calculateGst",
        "tags": [
          "calculators"
        ],
        "summary": "India GST: add or remove, CGST + SGST or IGST",
        "parameters": [
          {
            "name": "amount",
            "in": "query",
            "required": true,
            "description": "Rupees",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "rate",
            "in": "query",
            "required": false,
            "description": "Percent, default 18",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "add | remove",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "supply",
            "in": "query",
            "required": false,
            "description": "intra | inter",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GstResult"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/api/public/calc/vat": {
      "get": {
        "operationId": "calculateVat",
        "tags": [
          "calculators"
        ],
        "summary": "VAT: add or remove (UK, EU countries, UAE)",
        "parameters": [
          {
            "name": "amount",
            "in": "query",
            "required": true,
            "description": "Amount",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "rate",
            "in": "query",
            "required": false,
            "description": "Percent; default the country standard rate",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "add | remove",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "GB (default), DE, FR, NL, IE, ES, IT, BE, AT, PT, FI, AE",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/api/public/calc/emi": {
      "get": {
        "operationId": "calculateEmi",
        "tags": [
          "calculators"
        ],
        "summary": "Loan EMI with a yearly schedule",
        "parameters": [
          {
            "name": "principal",
            "in": "query",
            "required": true,
            "description": "Loan amount",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "annual_rate",
            "in": "query",
            "required": true,
            "description": "Percent a year",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "months",
            "in": "query",
            "required": false,
            "description": "Tenure in months",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "years",
            "in": "query",
            "required": false,
            "description": "Tenure in years (if no months)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Default INR",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/api/public/calc/gstin": {
      "get": {
        "operationId": "checkGstin",
        "tags": [
          "calculators"
        ],
        "summary": "GSTIN format check",
        "parameters": [
          {
            "name": "gstin",
            "in": "query",
            "required": true,
            "description": "The GSTIN",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/api/public/hsn": {
      "get": {
        "operationId": "findHsnCode",
        "tags": [
          "calculators"
        ],
        "summary": "Find an HSN or SAC code (India GST)",
        "description": "Searches HSN (goods) and SAC (services) codes by words or code digits. Each result has the official description, its chapter and heading, and the GST rate when checked against the rate notification (else null). The answer states the dataset scope. Same as the MCP tool find_hsn_code.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Words (laptop, legal services) or 2-8 digits of a code",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "all (default), hsn or sac",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-50, default 20",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matches",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "scope": {
                      "type": "string"
                    },
                    "as_of": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "HSN",
                              "SAC"
                            ]
                          },
                          "level": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "rate_percent": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "rate_note": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "path": {
                            "type": "array",
                            "items": {
                              "type": "object"
                            }
                          },
                          "sources": {
                            "type": "array",
                            "items": {
                              "type": "object"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/public/statement-pdf": {
      "post": {
        "operationId": "createStatementPdf",
        "tags": [
          "documents"
        ],
        "summary": "Branded PDF of a balance sheet or trial balance",
        "description": "The free PDF of /templates/balance-sheet-format (Schedule III) or /templates/trial-balance-format (with final accounts), with a LuckPanda footer and a verification code. Amounts are integer paise. Line and group ids: see the pages' .md twins.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "statement"
                ],
                "properties": {
                  "statement": {
                    "type": "object",
                    "required": [
                      "kind",
                      "rows"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": [
                          "balance_sheet",
                          "trial_balance"
                        ]
                      },
                      "business": {
                        "type": "string"
                      },
                      "as_at": {
                        "type": "string",
                        "format": "date"
                      },
                      "as_on": {
                        "type": "string",
                        "format": "date"
                      },
                      "entity": {
                        "type": "string",
                        "enum": [
                          "company",
                          "proprietorship",
                          "partnership",
                          "llp"
                        ]
                      },
                      "scale": {
                        "type": "string",
                        "enum": [
                          "rupees",
                          "thousands",
                          "lakhs",
                          "crores"
                        ]
                      },
                      "show_py": {
                        "type": "boolean"
                      },
                      "closing_stock": {
                        "type": "integer"
                      },
                      "final_accounts": {
                        "type": "boolean"
                      },
                      "rows": {
                        "type": "array",
                        "maxItems": 120,
                        "items": {
                          "type": "object"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The PDF",
            "content": {
              "application/pdf": {}
            }
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "429": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Document": {
        "type": "object",
        "description": "A document to prefill. Parts that fail validation are left out and listed in `ignored`; nothing is ever rendered as HTML.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "invoice",
              "quote",
              "proforma",
              "credit_note",
              "receipt"
            ],
            "description": "Document type."
          },
          "country_code": {
            "type": "string",
            "enum": [
              "US",
              "GB",
              "DE",
              "FR",
              "NL",
              "IE",
              "AE",
              "SG",
              "AU",
              "CA",
              "IN",
              "ES",
              "IT",
              "BE",
              "AT",
              "PT",
              "FI",
              "MX",
              "BR"
            ],
            "description": "The seller's country: decides currency, formats and tax rules. If missing: the currency's country (INR -> IN, GBP -> GB …; EUR -> DE unless the caller is in a euro country), else the caller's country."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "EUR",
              "GBP",
              "INR",
              "AED",
              "SGD",
              "AUD",
              "CAD",
              "MXN",
              "BRL"
            ],
            "description": "ISO 4217 code. If missing: the seller country's currency."
          },
          "seller": {
            "type": "object",
            "description": "Your business (who issues the document; for a receipt, who received the money).",
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 200
              },
              "address": {
                "type": "string",
                "maxLength": 600,
                "description": "New lines as \\n."
              },
              "email": {
                "type": "string",
                "maxLength": 200
              },
              "tax_id": {
                "type": "string",
                "maxLength": 60,
                "description": "GSTIN (India), VAT number (UK/EU), EIN (US), ABN, TRN..."
              },
              "country_code": {
                "type": "string",
                "pattern": "^[A-Za-z]{2}$",
                "description": "Buyer only; the seller's country is the document's country_code."
              },
              "state_code": {
                "type": "string",
                "description": "India: two-digit GST state code or the state name."
              }
            }
          },
          "buyer": {
            "type": "object",
            "description": "The client (for a receipt, who paid).",
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 200
              },
              "address": {
                "type": "string",
                "maxLength": 600,
                "description": "New lines as \\n."
              },
              "email": {
                "type": "string",
                "maxLength": 200
              },
              "tax_id": {
                "type": "string",
                "maxLength": 60,
                "description": "GSTIN (India), VAT number (UK/EU), EIN (US), ABN, TRN..."
              },
              "country_code": {
                "type": "string",
                "pattern": "^[A-Za-z]{2}$",
                "description": "Buyer only; the seller's country is the document's country_code."
              },
              "state_code": {
                "type": "string",
                "description": "India: two-digit GST state code or the state name."
              }
            }
          },
          "issue_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "YYYY-MM-DD. Default: today."
          },
          "due_date": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Due date; for a quote, valid until."
          },
          "lines": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "object",
              "properties": {
                "description": {
                  "type": "string",
                  "maxLength": 500
                },
                "quantity": {
                  "type": [
                    "string",
                    "number"
                  ],
                  "description": "Decimal, up to 6 decimals (\"1\", \"2.5\")."
                },
                "unit_price_minor": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Price per unit in minor units (cents, paise)."
                },
                "unit_price": {
                  "type": [
                    "string",
                    "number"
                  ],
                  "description": "Alternative: price per unit in major units (\"1250.50\")."
                },
                "tax_rate_bp": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 10000,
                  "description": "Tax rate in basis points: 18% = 1800."
                },
                "tax_percent": {
                  "type": [
                    "string",
                    "number"
                  ],
                  "description": "Alternative: tax rate in percent (18)."
                },
                "unit_code": {
                  "type": "string",
                  "description": "unit | hour | day | month | item"
                },
                "discount_minor": {
                  "type": "integer",
                  "minimum": 0
                },
                "hsn_sac": {
                  "type": "string",
                  "description": "India: HSN (goods, 4/6/8 digits) or SAC (services, 6 digits starting 99)."
                }
              }
            },
            "description": "The items or services, 1 to 100 lines."
          },
          "notes": {
            "type": "string",
            "maxLength": 2000,
            "description": "Shown on the document, for example a thank-you or a delivery note."
          },
          "terms": {
            "type": "string",
            "maxLength": 2000,
            "description": "Payment terms and bank details; for a quote, validity and delivery terms."
          },
          "place_of_supply": {
            "type": "string",
            "description": "India: GST state code, or 96 for another country."
          },
          "export_type": {
            "type": "string",
            "enum": [
              "none",
              "lut",
              "with_payment"
            ],
            "description": "India, buyer abroad."
          },
          "original_invoice_number": {
            "type": "string",
            "maxLength": 40,
            "description": "Credit notes: the invoice it corrects."
          },
          "original_invoice_date": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "reason": {
            "type": "string",
            "description": "Credit notes: refund, product_return, discount, price_correction, defect, cancellation, tax_correction, other, or the reason in your own words."
          },
          "reason_note": {
            "type": "string",
            "maxLength": 500
          }
        }
      },
      "StrictDocument": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Document"
          }
        ],
        "required": [
          "kind",
          "currency",
          "country_code",
          "seller",
          "buyer",
          "issue_date",
          "lines"
        ],
        "description": "As Document, all required, with lines in unit_price_minor and tax_rate_bp (the editor's own shape). locale defaults from the country."
      },
      "LinkRequest": {
        "type": "object",
        "required": [
          "doc"
        ],
        "properties": {
          "page": {
            "type": "string",
            "description": "The page to open: a slug (\"credit-note\", \"gst-invoice-format\") or its URL. Default: the generator for the document type and country."
          },
          "doc": {
            "$ref": "#/components/schemas/Document"
          }
        }
      },
      "LinkResult": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Short link /d/<id>"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "page": {
            "type": "string"
          },
          "prefill_url": {
            "type": "string",
            "description": "Self-contained ?doc= link, when under 6000 characters"
          },
          "document_type": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "totals": {
            "type": "object"
          },
          "missing": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Required fields still empty: ask the person."
          },
          "ignored": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Field paths left out because they were invalid."
          },
          "next_step": {
            "$ref": "#/components/schemas/NextStep"
          },
          "doc": {
            "$ref": "#/components/schemas/Document"
          }
        }
      },
      "NextStep": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "open_url": {
            "type": "string"
          },
          "signin_url": {
            "type": "string"
          },
          "needs_account": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "GstResult": {
        "type": "object",
        "properties": {
          "amount_before_gst": {
            "type": "number"
          },
          "gst": {
            "type": "number"
          },
          "amount_including_gst": {
            "type": "number"
          },
          "components": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "rate_percent": {
                  "type": "number"
                },
                "amount": {
                  "type": "number"
                }
              }
            }
          },
          "formatted": {
            "type": "object"
          }
        }
      },
      "Problem": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "field_errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                }
              }
            }
          },
          "correlation_id": {
            "type": "string"
          }
        }
      }
    },
    "responses": {
      "Problem": {
        "description": "Problem details (code, message, field_errors)",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    }
  }
}