Invovate โ† Back to Invoice Generator

Invoice Generator API Documentation

Generate professional PDF invoices programmatically via a simple REST API

v1.0

Overview

The Invovate invoice API lets developers generate professional invoices with a single HTTP POST request. Choose between a structured JSON response containing all calculations or a direct PDF download. The API supports 11 languages, 20+ currencies, and 5 design templates โ€” ideal for freelancers, SaaS platforms, and accounting applications that need invoice automation without building a rendering engine from scratch.

Free to Start

40 calls/hour, no credit card required

JSON or PDF

Choose your preferred output format

Tax Calculation

Per-line or global tax rates

Multilingual

en, nl, de, fr, es, ja and more

5 Templates

classic, modern, bold, minimal, navy

20+ Currencies

USD, EUR, GBP, JPY and more

Base URL:
https://invovate.com/api

Quick Start

Generate your first invoice in three steps:

Step 1 โ€” Create an account
Sign up for free at invovate.com and verify your email address.
Step 2 โ€” Get your API key
Go to the dashboard and click "Generate API Key". Your key will begin with inv_.
Step 3 โ€” Make your first call
curl -X POST https://invovate.com/api/generate-invoice \ -H "Content-Type: application/json" \ -H "Authorization: Bearer inv_yourapikey" \ -d '{ "from": {"name": "My Company Inc."}, "to": {"name": "Acme Corp"}, "items": [{"description": "Web Design", "quantity": 1, "unit_price": 1500, "tax_rate": 10}], "invoice": {"currency": "USD", "language": "en"} }'

Authentication

The API supports three authentication methods:

1. API Key (recommended for server-side use)

Pass your API key as a Bearer token in the Authorization header. All API keys start with inv_ and are generated from your account dashboard after email verification.

Authorization: Bearer inv_yourapikey

2. Session Cookie (for browser-based applications)

When you are logged in via the Invovate web application, the session cookie inv_session is sent automatically with same-origin requests. This is used internally by the dashboard and does not require a separate API key.

3. Anonymous (unauthenticated)

Calls without authentication are permitted but restricted to JSON output only and rate-limited by IP address. This mode is suitable for testing the API shape without registering.

Security: Never embed your API key in client-side JavaScript or commit it to a Git repository. Store it in an environment variable on your server and inject it at runtime.

Rate Limits & Plans

PlanPricePer HourPer Week
Free$040400
Starter$9/month2004,000
Pro$29/month1,00040,000
EnterpriseContact usUnlimitedUnlimited

Current usage is tracked in the response headers on every successful call:

X-RateLimit-Limit-Hourly: 40 X-RateLimit-Remaining-Hourly: 39 X-RateLimit-Reset-Hourly: 1712123456 X-RateLimit-Limit-Weekly: 400 X-RateLimit-Remaining-Weekly: 399 X-RateLimit-Reset-Weekly: 1712345678

When the rate limit is exceeded the API returns HTTP 429 Too Many Requests. The reset_at values are Unix timestamps indicating when the window resets.

Generate Invoice

POST
/api/generate-invoice

Generates an invoice and returns either a JSON object containing all calculated totals or a binary PDF file, depending on the output field in the request body.

Authenticated requests (API key or session) use your account's hourly and weekly credit windows. Anonymous requests are rate-limited per IP and restricted to JSON output.

Request Schema

Send a JSON body with Content-Type: application/json. All monetary values are plain numbers (no currency symbol). The only hard requirements are from.name, to.name, and at least one item in the items array.

Sender (from)

FieldTypeRequiredDescription
from.namestringYesYour business name
from.addressstringNoYour business address (multiline supported)
from.emailstringNoYour contact email address
from.phonestringNoYour phone number
from.tax_idstringNoVAT or tax registration number (e.g. GB123456789)

Recipient (to)

FieldTypeRequiredDescription
to.namestringYesClient or company name
to.addressstringNoClient billing address
to.emailstringNoClient email address
to.phonestringNoClient phone number

Invoice Metadata (invoice)

FieldTypeDefaultDescription
invoice.numberstringAutoInvoice number (e.g. INV-2026-001)
invoice.datestringTodayIssue date in YYYY-MM-DD format
invoice.due_datestringโ€”Payment due date in YYYY-MM-DD format
invoice.currencystringUSDISO 4217 currency code (e.g. USD, EUR, GBP)
invoice.languagestringenBCP 47 language code (e.g. en, nl, de)
invoice.termsstringโ€”Payment terms text (e.g. "Net 30 days")
invoice.po_numberstringโ€”Purchase order number for the client's records

Line Items (items array)

At least one item is required. Each element in the array represents one line on the invoice.

FieldTypeRequiredDescription
descriptionstringYesProduct or service description
quantitynumberYesNumber of units
unit_pricenumberYesPrice per unit (before tax and discount)
discountnumberNoLine-level discount value
discount_typestringpercent"percent" (e.g. 10 = 10%) or "amount" (e.g. 50 = $50 off)
tax_ratenumberNoPer-line tax percentage (e.g. 20 for 20% VAT). Overrides global_tax for this line.

Top-level Fields

FieldTypeDescription
global_taxnumberTax percentage applied to all lines that do not have their own tax_rate
global_discountnumberDiscount applied to the invoice subtotal (after per-line discounts)
global_discount_typestring"percent" or "amount"
amount_paidnumberAmount already received (used to calculate balance due)
notesstringFree-text notes shown at the bottom of the invoice
refund_policystringRefund or returns policy text
templatestringPDF template name: classic, modern, bold, minimal, navy (default: classic)
outputstring"json" (default) or "pdf"

Response Format

JSON response (output: "json")

Returns 200 OK with Content-Type: application/json.

{ "success": true, "invoice": { "number": "INV-2026-001", "date": "2026-04-03", "due_date": "2026-05-03", "currency": "USD", "language": "en", "template": "classic", "from": { "name": "My Company Inc.", "address": "123 Main St, New York, NY 10001", "tax_id": "US-XX-1234567" }, "to": { "name": "Acme Corp", "email": "[email protected]" }, "items": [ { "description": "Web Development", "quantity": 1, "unit_price": 3500, "discount": 0, "tax_rate": 0, "tax_amount": 0, "line_total": 3500.00 }, { "description": "Monthly Hosting", "quantity": 12, "unit_price": 25, "discount": 10, "discount_type": "percent", "tax_rate": 0, "tax_amount": 0, "line_total": 270.00 } ], "subtotal": 3770.00, "global_discount": 0, "total_tax": 0, "grand_total": 3770.00, "amount_paid": 500.00, "balance_due": 3270.00, "notes": "Thank you for your business!" }, "meta": { "processing_ms": 9, "credits_remaining": { "hourly": 39, "weekly": 399 }, "rate_limits": { "hourly": { "limit": 40, "used": 1, "reset_at": 1712123456 }, "weekly": { "limit": 400, "used": 1, "reset_at": 1712345678 } } } }

PDF response (output: "pdf")

Returns 200 OK with a binary PDF body. Save the response bytes directly to a .pdf file.

Content-Type: application/pdf Content-Disposition: attachment; filename="invoice.pdf"
Note: PDF output requires an authenticated request (API key or session cookie). Anonymous calls with output: "pdf" will receive a 401 error.

Error Codes

All error responses share a consistent JSON structure:

{ "success": false, "error": { "message": "At least one line item is required" } }
HTTP StatusMeaning
400Validation error โ€” check your request body. The error.message field describes the specific problem.
401Authentication required, or the provided API key is invalid or expired.
403Email address not yet verified. Check your inbox for the verification link.
429Rate limit exceeded. Check the X-RateLimit-Reset-Hourly header to see when your window resets.
500Internal server error. If this persists, contact support via invovate.com.

Auth Endpoints

Use these endpoints to register, log in, and retrieve or generate your API key programmatically.

POST
/api/auth/register

Create a new account. Sends a verification email automatically.

// Request body { "email": "[email protected]", "password": "yourpassword" } // Success response (201) { "success": true, "message": "Verification email sent" }
POST
/api/auth/login

Log in with email and password. Returns a session cookie (inv_session) on success.

// Request body { "email": "[email protected]", "password": "yourpassword" } // Success response (200) { "success": true, "user": { "email": "[email protected]", "tier": "free" } }
GET
/api/auth/me

Returns the currently authenticated user's profile, tier, and API key (if generated).

// Requires: Authorization header or session cookie // Success response (200) { "success": true, "user": { "email": "[email protected]", "tier": "free", "api_key": "inv_xxxxxxxxxxxx", "credits": { "total": 400, "used": 1 } } }
POST
/api/auth/generate-api-key

Generates a new API key for the authenticated user. Requires a verified email address. Calling this endpoint rotates the existing key immediately โ€” update your integrations before regenerating.

// Requires: Authorization header or session cookie // Success response (200) { "success": true, "api_key": "inv_xxxxxxxxxxxx" }
MethodPathDescription
POST/api/auth/registerCreate a new account with email and password
POST/api/auth/loginLog in, returns session cookie
POST/api/auth/logoutInvalidates the current session
GET/api/auth/meReturns current user info and API key
POST/api/auth/generate-api-keyRotate API key (verified email required)
POST/api/auth/resend-verificationResend the email verification link

Code Examples

cURL โ€” PDF invoice with tax

curl -X POST https://invovate.com/api/generate-invoice \ -H "Content-Type: application/json" \ -H "Authorization: Bearer inv_yourapikey" \ -d '{ "from": { "name": "Bright Studio LLC", "address": "742 Evergreen Terrace, Springfield, IL 62701", "email": "[email protected]", "tax_id": "US-12-3456789" }, "to": { "name": "Globex Corporation", "address": "100 Industrial Way, Shelbyville, TN 37160", "email": "[email protected]" }, "invoice": { "number": "INV-2026-042", "date": "2026-04-03", "due_date": "2026-05-03", "currency": "USD", "language": "en", "terms": "Net 30" }, "items": [ { "description": "Brand identity design", "quantity": 1, "unit_price": 4200.00, "tax_rate": 8.5 }, { "description": "Social media assets (monthly)", "quantity": 3, "unit_price": 350.00, "tax_rate": 8.5 } ], "notes": "Thank you for choosing Bright Studio!", "template": "modern", "output": "pdf" }' --output invoice.pdf

JavaScript (Node.js / fetch)

// Generate a JSON invoice with the Invovate API const response = await fetch('https://invovate.com/api/generate-invoice', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer inv_yourapikey' }, body: JSON.stringify({ from: { name: 'Bright Studio LLC', tax_id: 'US-12-3456789' }, to: { name: 'Globex Corporation', email: '[email protected]' }, invoice: { number: 'INV-2026-001', currency: 'USD', language: 'en', due_date: '2026-05-03', terms: 'Net 30' }, items: [ { description: 'Consulting', quantity: 8, unit_price: 200, tax_rate: 0 } ], output: 'json' }) }); const data = await response.json(); if (data.success) { console.log('Grand total:', data.invoice.grand_total, data.invoice.currency); console.log('Remaining calls this hour:', data.meta.credits_remaining.hourly); } else { console.error('Error:', data.error.message); } // Downloading a PDF instead async function downloadPDF() { const res = await fetch('https://invovate.com/api/generate-invoice', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer inv_yourapikey' }, body: JSON.stringify({ ...invoicePayload, output: 'pdf' }) }); const buffer = await res.arrayBuffer(); require('fs').writeFileSync('invoice.pdf', Buffer.from(buffer)); console.log('PDF saved to invoice.pdf'); }

Python

import requests API_KEY = "inv_yourapikey" URL = "https://invovate.com/api/generate-invoice" payload = { "from": { "name": "Bright Studio LLC", "address": "742 Evergreen Terrace, Springfield, IL 62701", "tax_id": "US-12-3456789" }, "to": { "name": "Globex Corporation", "address": "100 Industrial Way, Shelbyville, TN 37160", "email": "[email protected]" }, "invoice": { "number": "INV-2026-001", "currency": "USD", "language": "en", "due_date": "2026-05-03", "terms": "Net 30" }, "items": [ {"description": "Web development", "quantity": 1, "unit_price": 3500, "tax_rate": 0}, {"description": "Hosting setup", "quantity": 1, "unit_price": 250, "tax_rate": 0} ], "template": "navy", "output": "pdf" } headers = {"Authorization": f"Bearer {API_KEY}"} response = requests.post(URL, json=payload, headers=headers) if response.status_code == 200: with open("invoice.pdf", "wb") as f: f.write(response.content) print("Invoice saved as invoice.pdf") else: error = response.json() print(f"Error: {error['error']['message']}") # JSON output example payload_json = {**payload, "output": "json"} response = requests.post(URL, json=payload_json, headers=headers) data = response.json() if data["success"]: inv = data["invoice"] print(f"Invoice {inv['number']}: ${inv['grand_total']:.2f} due {inv['due_date']}")

Supported Languages

The invoice.language field controls the locale used for labels, date formatting, and number formatting on the generated invoice.

CodeLanguageDirection
enEnglishLTR
nlDutchLTR
deGermanLTR
frFrenchLTR
esSpanishLTR
itItalianLTR
ptPortugueseLTR
ruRussianLTR
hiHindiLTR
jaJapaneseLTR
arArabicRTL

PDF Templates

Pass the template name in the top-level template field. The default is classic.

NameStyle Description
classicBlue accent, alternating grey rows โ€” professional and broadly compatible (default)
modernTeal/cyan header, clean sans-serif feel โ€” ideal for creative agencies and tech companies
boldDark charcoal header, high-contrast typography โ€” strong visual impact
minimalLight grey, borderless layout โ€” understated elegance for luxury brands
navyDeep navy header with gold accent line โ€” authoritative, suited to finance and consulting

Supported Currencies

Pass the ISO 4217 code in invoice.currency. The currency symbol is rendered automatically on the PDF and included in JSON totals.

CodeCurrency
USDUS Dollar
EUREuro
GBPBritish Pound
JPYJapanese Yen
CADCanadian Dollar
AUDAustralian Dollar
CHFSwiss Franc
CNYChinese Yuan
INRIndian Rupee
AEDUAE Dirham
SARSaudi Riyal
SGDSingapore Dollar
NZDNew Zealand Dollar
KRWSouth Korean Won
BRLBrazilian Real
MXNMexican Peso
ZARSouth African Rand
SEKSwedish Krona
NOKNorwegian Krone
DKKDanish Krone