{
  "title": "Quote generator",
  "human_url": "https://happytails.ai/en/api/tools/quote-generator/",
  "agent_url": "https://happytails.ai/agents/en/api/tools/quote-generator/",
  "language": "en",
  "markdown_url": "https://happytails.ai/en/api/tools/quote-generator.md",
  "content": "API reference\nQuote generator\nBusiness estimate template with validity and line items.\nPOST\n/api/v1/tools/quote-generator/run\nBase URL: https://happytails.ai\n· public API not connected\nOverview\nBasic line-item PDF, with tax added after subtotal and amounts rounded to cents. Review local invoice requirements. Standard font supports basic Latin text.\nAll API requests process supplied data on the server.\nRequest parameters\nSend a JSON object. Unknown properties are rejected. Omitted options use the defaults below; enter numbers and booleans as JSON values, not quoted text.\ninput\nis a string, empty by default, up to 1,000,000 characters. Enter a JSON array of items with description, quantity and price. Fill in the business and customer details below. Up to 1,000,000 characters. Review the settings before running.\nThis endpoint does not accept a\nfiles\narray.\nOptions\noptions.number\nstring\nDocument number\nDefault:\n\"INV-001\"\noptions.from\nstring\nYour business\nDefault:\n\"\"\noptions.to\nstring\nCustomer\nDefault:\n\"\"\noptions.date\nstring\nDate\nDefault:\n\"2026-09-28\"\noptions.currency\nstring\nCurrency\nDefault:\n\"EUR\"\noptions.tax\nnumber\nTax (%)\nDefault:\n0.0\nSuccess response\nHTTP 200 returns\ntool\nand\nresult\n. Text is in\nresult.text\n; parsed JSON may also appear in\nresult.data\n. Generated files are in\nresult.files\nwith\nname\n,\nmime\n,\nbytes\nand\nbase64\n. Decode the bytes before saving. Empty file arrays and null text are valid for operations returning another result type.\nComplete output schema\n{\n\"type\": \"object\",\n\"required\": [\n\"tool\",\n\"result\"\n],\n\"properties\": {\n\"tool\": {\n\"type\": \"string\"\n},\n\"result\": {\n\"type\": \"object\",\n\"required\": [\n\"text\",\n\"files\"\n],\n\"properties\": {\n\"text\": {\n\"type\": [\n\"string\",\n\"null\"\n]\n},\n\"data\": {\n\"description\": \"Parsed JSON when the textual result is JSON.\"\n},\n\"name\": {\n\"type\": \"string\"\n},\n\"mime\": {\n\"type\": \"string\"\n},\n\"files\": {\n\"type\": \"array\",\n\"items\": {\n\"type\": \"object\",\n\"required\": [\n\"name\",\n\"mime\",\n\"bytes\",\n\"base64\"\n],\n\"properties\": {\n\"name\": {\n\"type\": \"string\"\n},\n\"mime\": {\n\"type\": \"string\"\n},\n\"bytes\": {\n\"type\": \"integer\"\n},\n\"base64\": {\n\"type\": \"string\",\n\"contentEncoding\": \"base64\"\n}\n}\n}\n}\n}\n}\n}\n}\nLimits and failures\nLimits below are enforced by this endpoint. Additional format, page, duration and model limits in the behavior notes also apply. Browser UI limits can differ from API limits.\nrequest_bytes\n8388608\ninput_characters\n1000000\nfiles_bytes\n5242880\nmax_files\n0\ntimeout_seconds\n12\nInvalid requests return an\nerror\nobject with\ncode\nand\nmessage\n. Read\nHTTP statuses, retries, timeouts and concurrency\n. Execution is synchronous and results are returned in the response.\nComplete request schema\nExpand the JSON schema\n{\n\"type\": \"object\",\n\"additionalProperties\": false,\n\"properties\": {\n\"input\": {\n\"type\": \"string\",\n\"maxLength\": 1000000,\n\"default\": \"\",\n\"description\": \"Plain text input. File tools use files instead unless otherwise documented.\"\n},\n\"options\": {\n\"type\": \"object\",\n\"additionalProperties\": false,\n\"properties\": {\n\"number\": {\n\"type\": \"string\",\n\"description\": \"Document number\",\n\"default\": \"INV-001\"\n},\n\"from\": {\n\"type\": \"string\",\n\"description\": \"Your business\",\n\"default\": \"\"\n},\n\"to\": {\n\"type\": \"string\",\n\"description\": \"Customer\",\n\"default\": \"\"\n},\n\"date\": {\n\"type\": \"string\",\n\"description\": \"Date\",\n\"default\": \"2026-09-28\"\n},\n\"currency\": {\n\"type\": \"string\",\n\"description\": \"Currency\",\n\"default\": \"EUR\"\n},\n\"tax\": {\n\"type\": \"number\",\n\"description\": \"Tax (%)\",\n\"default\": 0.0\n}\n}\n}\n}\n}\nFor browser automation, use the central\nWebMCP guidance\nand discover the tools actually exposed by the browser.\nRequest example\ncURL\ncurl https://happytails.ai/api/v1/tools/quote-generator/run \\\n-H \"Content-Type: application/json\" \\\n--data '{\"options\": {\"number\": \"INV-001\", \"from\": \"\", \"to\": \"\", \"date\": \"2026-09-28\", \"currency\": \"EUR\", \"tax\": 0.0}, \"input\": \"Your input\"}'\nJavaScript\nconst payload = {\n\"options\": {\n\"number\": \"INV-001\",\n\"from\": \"\",\n\"to\": \"\",\n\"date\": \"2026-09-28\",\n\"currency\": \"EUR\",\n\"tax\": 0.0\n},\n\"input\": \"Your input\"\n};\nconst response = await fetch(\n\"https://happytails.ai/api/v1/tools/quote-generator/run\",\n{\nmethod: \"POST\",\nheaders: { \"Content-Type\": \"application/json\" },\nbody: JSON.stringify(payload)\n}\n);\nconst data = await response.json();\nif (!response.ok) throw new Error(data.error.message);\nconsole.log(data.result);\nPython\nimport json\nfrom urllib.request import Request, urlopen\npayload = json.loads('{\"options\": {\"number\": \"INV-001\", \"from\": \"\", \"to\": \"\", \"date\": \"2026-09-28\", \"currency\": \"EUR\", \"tax\": 0.0}, \"input\": \"Your input\"}')\nrequest = Request(\n\"https://happytails.ai/api/v1/tools/quote-generator/run\",\ndata=json.dumps(payload).encode(),\nheaders={\"Content-Type\": \"application/json\"},\n)\nwith urlopen(request, timeout=200) as response:\nresult = json.load(response)\nprint(result)\nJSON\n{\n\"options\": {\n\"number\": \"INV-001\",\n\"from\": \"\",\n\"to\": \"\",\n\"date\": \"2026-09-28\",\n\"currency\": \"EUR\",\n\"tax\": 0.0\n},\n\"input\": \"Your input\"\n}\nReplace the API origin and input values for your application.\n200 OK · response structure\nJSON\n{\n\"tool\": \"quote-generator\",\n\"result\": {\n\"text\": null,\n\"files\": []\n}\n}\nIllustrative envelope. Actual text, filename, MIME type and bytes depend on the result. See the complete output schema.\n400 Bad Request\nJSON\n{\n\"error\": {\n\"code\": \"INVALID_INPUT\",\n\"message\": \"Unknown request property. See the tool input schema.\"\n}\n}",
  "content_format": "text/plain",
  "visibility": "public",
  "links": [
    {
      "name": "HTTP statuses, retries, timeouts and concurrency",
      "url": "https://happytails.ai/en/api/#limits"
    },
    {
      "name": "WebMCP guidance",
      "url": "https://happytails.ai/en/api/#browser-agents"
    }
  ],
  "markdown": "# Quote generator\n\n- Human page: https://happytails.ai/en/api/tools/quote-generator/\n- Markdown: https://happytails.ai/en/api/tools/quote-generator.md\n- Structured JSON: https://happytails.ai/agents/en/api/tools/quote-generator/index.json\n- Visibility: public\n\n## Page guide\n\nAPI reference\n\nBusiness estimate template with validity and line items.\n\nPOST\n\n/api/v1/tools/quote-generator/run\n\nBase URL: https://happytails.ai · public API not connected\n\n## Overview\n\nBasic line-item PDF, with tax added after subtotal and amounts rounded to cents. Review local invoice requirements. Standard font supports basic Latin text.\n\nAll API requests process supplied data on the server.\n\n## Request parameters\n\nSend a JSON object. Unknown properties are rejected. Omitted options use the defaults below; enter numbers and booleans as JSON values, not quoted text.\n\n`input` is a string, empty by default, up to 1,000,000 characters. Enter a JSON array of items with description, quantity and price. Fill in the business and customer details below. Up to 1,000,000 characters. Review the settings before running.\n\nThis endpoint does not accept a `files` array.\n\n### Options\n\n#### `options.number`\n\nType: string\n\nDocument number\n\nDefault: `\"INV-001\"`\n\n#### `options.from`\n\nType: string\n\nYour business\n\nDefault: `\"\"`\n\n#### `options.to`\n\nType: string\n\nCustomer\n\nDefault: `\"\"`\n\n#### `options.date`\n\nType: string\n\nDate\n\nDefault: `\"2026-09-28\"`\n\n#### `options.currency`\n\nType: string\n\nCurrency\n\nDefault: `\"EUR\"`\n\n#### `options.tax`\n\nType: number\n\nTax (%)\n\nDefault: `0.0`\n\n## Success response\n\nHTTP 200 returns `tool` and `result`. Text is in `result.text`; parsed JSON may also appear in `result.data`. Generated files are in `result.files` with `name`, `mime`, `bytes` and `base64`. Decode the bytes before saving. Empty file arrays and null text are valid for operations returning another result type.\n\n### Complete output schema\n\n```json\n{\n  \"type\": \"object\",\n  \"required\": [\n    \"tool\",\n    \"result\"\n  ],\n  \"properties\": {\n    \"tool\": {\n      \"type\": \"string\"\n    },\n    \"result\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"text\",\n        \"files\"\n      ],\n      \"properties\": {\n        \"text\": {\n          \"type\": [\n            \"string\",\n            \"null\"\n          ]\n        },\n        \"data\": {\n          \"description\": \"Parsed JSON when the textual result is JSON.\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"mime\": {\n          \"type\": \"string\"\n        },\n        \"files\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"object\",\n            \"required\": [\n              \"name\",\n              \"mime\",\n              \"bytes\",\n              \"base64\"\n            ],\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"mime\": {\n                \"type\": \"string\"\n              },\n              \"bytes\": {\n                \"type\": \"integer\"\n              },\n              \"base64\": {\n                \"type\": \"string\",\n                \"contentEncoding\": \"base64\"\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n## Limits and failures\n\nLimits below are enforced by this endpoint. Additional format, page, duration and model limits in the behavior notes also apply. Browser UI limits can differ from API limits.\n\n| Field | Value |\n| --- | --- |\n| `request_bytes` | 8388608 |\n| `input_characters` | 1000000 |\n| `files_bytes` | 5242880 |\n| `max_files` | 0 |\n| `timeout_seconds` | 12 |\n\nInvalid requests return an `error` object with `code` and `message`. Read [HTTP statuses, retries, timeouts and concurrency](https://happytails.ai/en/api/#limits). Execution is synchronous and results are returned in the response.\n\n## Complete request schema\n\n### Expand the JSON schema\n\n```json\n{\n  \"type\": \"object\",\n  \"additionalProperties\": false,\n  \"properties\": {\n    \"input\": {\n      \"type\": \"string\",\n      \"maxLength\": 1000000,\n      \"default\": \"\",\n      \"description\": \"Plain text input. File tools use files instead unless otherwise documented.\"\n    },\n    \"options\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"number\": {\n          \"type\": \"string\",\n          \"description\": \"Document number\",\n          \"default\": \"INV-001\"\n        },\n        \"from\": {\n          \"type\": \"string\",\n          \"description\": \"Your business\",\n          \"default\": \"\"\n        },\n        \"to\": {\n          \"type\": \"string\",\n          \"description\": \"Customer\",\n          \"default\": \"\"\n        },\n        \"date\": {\n          \"type\": \"string\",\n          \"description\": \"Date\",\n          \"default\": \"2026-09-28\"\n        },\n        \"currency\": {\n          \"type\": \"string\",\n          \"description\": \"Currency\",\n          \"default\": \"EUR\"\n        },\n        \"tax\": {\n          \"type\": \"number\",\n          \"description\": \"Tax (%)\",\n          \"default\": 0.0\n        }\n      }\n    }\n  }\n}\n```\n\nFor browser automation, use the central [WebMCP guidance](https://happytails.ai/en/api/#browser-agents) and discover the tools actually exposed by the browser.\n\nRequest example\n\n### cURL\n\n```bash\ncurl https://happytails.ai/api/v1/tools/quote-generator/run \\\n  -H \"Content-Type: application/json\" \\\n  --data '{\"options\": {\"number\": \"INV-001\", \"from\": \"\", \"to\": \"\", \"date\": \"2026-09-28\", \"currency\": \"EUR\", \"tax\": 0.0}, \"input\": \"Your input\"}'\n```\n\n### JavaScript\n\n```javascript\nconst payload = {\n  \"options\": {\n    \"number\": \"INV-001\",\n    \"from\": \"\",\n    \"to\": \"\",\n    \"date\": \"2026-09-28\",\n    \"currency\": \"EUR\",\n    \"tax\": 0.0\n  },\n  \"input\": \"Your input\"\n};\n\nconst response = await fetch(\n  \"https://happytails.ai/api/v1/tools/quote-generator/run\",\n  {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify(payload)\n  }\n);\nconst data = await response.json();\nif (!response.ok) throw new Error(data.error.message);\nconsole.log(data.result);\n```\n\n### Python\n\n```python\nimport json\nfrom urllib.request import Request, urlopen\n\npayload = json.loads('{\"options\": {\"number\": \"INV-001\", \"from\": \"\", \"to\": \"\", \"date\": \"2026-09-28\", \"currency\": \"EUR\", \"tax\": 0.0}, \"input\": \"Your input\"}')\n\nrequest = Request(\n    \"https://happytails.ai/api/v1/tools/quote-generator/run\",\n    data=json.dumps(payload).encode(),\n    headers={\"Content-Type\": \"application/json\"},\n)\nwith urlopen(request, timeout=200) as response:\n    result = json.load(response)\n    print(result)\n```\n\n### JSON\n\n```json\n{\n  \"options\": {\n    \"number\": \"INV-001\",\n    \"from\": \"\",\n    \"to\": \"\",\n    \"date\": \"2026-09-28\",\n    \"currency\": \"EUR\",\n    \"tax\": 0.0\n  },\n  \"input\": \"Your input\"\n}\n```\n\nReplace the API origin and input values for your application.\n\n200 OK · response structure\n\n### JSON\n\n```json\n{\n  \"tool\": \"quote-generator\",\n  \"result\": {\n    \"text\": null,\n    \"files\": []\n  }\n}\n```\n\nIllustrative envelope. Actual text, filename, MIME type and bytes depend on the result. See the complete output schema.\n\n400 Bad Request\n\n### JSON\n\n```json\n{\n  \"error\": {\n    \"code\": \"INVALID_INPUT\",\n    \"message\": \"Unknown request property. See the tool input schema.\"\n  }\n}\n```\n"
}