I Got Tired of Filling Invoices by Hand So I Built an API That Generates Proforma Invoice Debit and Credit Notes From JSON

The moment that finally broke the routine was a Tuesday afternoon spent staring at three separate invoice templates open in three separate applications. One company needed a standard VAT invoice for a client in Germany. Another needed a proforma invoice for a prepayment arrangement with a distributor. The third needed a credit note to correct an overbilling from the previous quarter. Three companies, three document types, three completely different workflows, and approximately two hours of manual data entry ahead before any of them would be ready to send. The numbers were already calculated. The client details were already known. The line items were sitting in a spreadsheet. And yet the actual process of getting those numbers into a properly formatted, professionally designed PDF felt like transcribing a novel by hand when a printer was sitting right there on the desk.

This was not a one-time annoyance. It was the monthly ritual. Every billing cycle brought the same tedious sequence: open the template, update the invoice number manually (and double check that the sequence had not been accidentally reused), fill in the client's address, copy line items one by one, verify the tax calculations, export to PDF, and send. Multiply that by three companies with different branding, different VAT rates, different numbering sequences, and different legal requirements, and the monthly invoicing process consumed the better part of a working day. A full day every month dedicated to a task that was pure data formatting with zero creative or strategic value.

The tools that existed were not solving the right problem. QuickBooks, FreshBooks, Zoho Invoice, and the rest all wanted to become the entire accounting backbone of the business. They wanted bank connections, expense tracking, payroll integration, and a monthly subscription for the privilege. What was needed was far simpler: send structured data in, get a beautifully formatted PDF out. Nothing more. No dashboard, no ledger, no twelve-step onboarding wizard. Just a function that accepts JSON and returns a document.

Three Companies and the Mess That Monthly Billing Creates

Running multiple companies is not as glamorous as LinkedIn posts make it sound. The operational overhead multiplies in ways that are not immediately obvious, and invoicing is one of the sneakiest culprits. Each company has its own legal entity, its own tax identification number, its own bank details, its own logo, and its own client base. A single invoicing tool that works perfectly for one company may be entirely wrong for another because the VAT structure differs, or because one company bills in euros while another bills in a local currency, or because the legal footer requirements change based on the jurisdiction of incorporation.

The manual approach involved maintaining Word document templates for each company. These templates were painstakingly formatted with logos, font choices, color accents, and carefully positioned fields. Updating them was a nightmare. If the company phone number changed, that change needed to propagate across every template variant: invoice, proforma, credit note, debit note, and receipt. Five document types times three companies equals fifteen templates to maintain, and every single one of them was a potential source of errors. Typos in bank details, wrong VAT registration numbers, outdated addresses. These are not trivial mistakes when the documents are legal records that may be audited years later.

The invoice numbering problem deserves its own paragraph because it caused actual business consequences. Sequential invoice numbering is a legal requirement in many jurisdictions. Gaps in the sequence raise red flags during audits. Duplicates are worse. Maintaining separate numbering sequences for three companies across five document types meant tracking fifteen different counters manually. A shared spreadsheet served as the "system of record" for these sequences, and on more than one occasion the spreadsheet was updated after the invoice was already sent, creating confusion about whether invoice number 2024-0047 had actually been issued or was still pending. The invoice generator that eventually replaced this chaos handles auto-numbering per company and per document type, eliminating an entire category of bookkeeping errors.

There was also the issue of document relationships. A proforma invoice is issued before the work begins. The final invoice references that proforma. If a correction is needed, a credit note references the original invoice. A debit note does the same for underbilling. These documents form a chain, and maintaining that chain manually across Word documents and spreadsheets is an exercise in controlled chaos. One mistyped reference number and the audit trail breaks.

What the API Actually Does and Why JSON Changes Everything

The invoicing API accepts a JSON payload containing all the structured data that an invoice requires: seller details, buyer details, line items with quantities and unit prices, tax rates, currency, payment terms, notes, and document metadata like the invoice number and issue date. It processes that payload and returns a fully rendered PDF document. The entire round trip takes seconds. No templates to open, no fields to fill, no manual calculations to verify.

Five document types are supported from the same endpoint family. A standard invoice is the most common, but the proforma invoice generator handles prepayment scenarios where the document needs to look and feel like an invoice without carrying the legal weight of one. Credit notes handle refunds and corrections by referencing the original invoice number and showing the adjusted amounts. Debit notes handle the opposite case, where additional charges need to be documented after the original invoice was issued. Receipts confirm that payment was received, closing the loop on the transaction. All five types share the same JSON structure with minor variations, which means the integration work is done once and every document type comes along for free.

The JSON approach is what makes the system genuinely useful rather than just another invoice tool with an API bolted on as an afterthought. Because the input is structured data rather than form fields, it can come from anywhere. An e-commerce platform can generate invoices automatically when an order ships. A CRM can trigger a proforma invoice when a deal moves to a specific stage. A spreadsheet export can be transformed into a batch of invoices with a simple script. The data source does not matter. As long as it can produce valid JSON, the API will produce valid documents. This composability is the fundamental advantage over traditional invoicing software, which assumes that a human will always be sitting in front of a form clicking buttons.

One of the more satisfying integrations connects the invoicing API with a document scanner. Incoming invoices from suppliers are scanned and parsed to extract line items, amounts, and vendor details. That extracted data feeds directly into the invoicing API to generate the corresponding outgoing documents, whether it is a matching payment receipt or a credit note disputing a charge. The loop from paper to structured data to generated document closes without manual data entry at any point in the chain.

Five Document Types and When Each One Matters

The distinction between these five document types is something that many small business owners learn the hard way, usually when an accountant or tax authority points out that the wrong type was used. A proforma invoice is not a tax document. Issuing one where a standard invoice was required can create compliance headaches. Conversely, issuing a full invoice before the goods are delivered or the service is rendered can create revenue recognition problems. Understanding which type to use and when is essential, and having a system that supports all five without requiring five separate tools or five separate workflows removes a meaningful source of friction.

A standard invoice is the document most people think of when they hear the word "invoice." It is a legal request for payment that records a completed transaction. It carries a unique sequential number, the full legal details of both parties, a breakdown of line items, applicable taxes, and payment instructions. It is the document that gets filed with tax returns and produced during audits. The invoicing API generates these with all required fields populated from the JSON input, including calculated totals, tax breakdowns, and formatted currency values. Nothing is left for the user to compute manually.

A proforma invoice looks nearly identical but serves a different purpose. It is a quotation dressed up as an invoice, used to formalize a price agreement before the transaction occurs. International trade relies heavily on proforma invoices for customs declarations and import permits. Freelancers use them to request deposits before starting work. The key difference is that a proforma does not enter the accounting ledger as revenue until a corresponding final invoice is issued. The API handles this distinction by marking the document type clearly in the header and adjusting the language of payment terms accordingly, so there is never ambiguity about whether a document is a binding invoice or a preliminary estimate.

Credit notes and debit notes are corrective documents, and they are where manual invoicing processes fall apart most spectacularly. A credit note reduces the amount owed by the buyer, typically because of a returned product, a pricing error, or a negotiated discount applied after the original invoice was issued. A debit note increases the amount owed, perhaps because additional services were rendered or because the original invoice undercharged due to a calculation mistake. Both types must reference the original invoice number, and both must flow through the accounting system to adjust the outstanding balance. Generating these manually means opening the original invoice, finding its number, creating a new document with the correct format, entering the adjustment amounts, and making sure the reference chain is intact. The API handles all of this from a single JSON payload that includes the original document reference.

Receipts are the simplest type but surprisingly absent from most invoicing tools. A receipt confirms that payment has been received. It references the invoice that was paid, states the amount and date of payment, and serves as proof of transaction for the buyer. Many businesses skip receipts entirely and rely on bank transfer confirmations instead, but in cash-heavy industries or in jurisdictions where official receipts are required for tax deductions, having a proper receipt generation capability is not optional. The API generates receipts that match the visual branding of the corresponding invoices, maintaining a consistent look across all documents issued by the same company.

Auto-numbering and the Sanity It Preserves

The auto-numbering feature alone justified the entire development effort. Each company maintains its own numbering sequence. Each document type within that company maintains its own sub-sequence. Invoice numbers follow one pattern, proforma invoices follow another, and credit notes follow a third. The sequences increment automatically with every generated document, and the format is configurable: some companies prefer a simple numeric sequence like 001, 002, 003, while others want a year prefix like 2026-001, and still others want a company code prefix like ABC-INV-001. The API accommodates all of these formats through a template string in the company configuration, and the actual counter is managed server-side so there is zero risk of duplicate numbers or accidental gaps.

This might sound like a minor detail, but for anyone who has ever had to explain a gap in their invoice sequence to a tax inspector, it is anything but minor. In several European countries, gaps in invoice numbering are treated as presumptive evidence of unreported income. The burden of proof shifts to the business to demonstrate that the gap was accidental rather than an attempt to hide a transaction. An automated, server-managed counter eliminates this risk entirely. Every number is sequential, every number is used, and the audit trail is maintained by the system rather than by a human with a spreadsheet and an imperfect memory.

The numbering system also handles the relationship between document types. When a credit note is issued against invoice 2026-042, the credit note carries its own number in its own sequence (say, CN-2026-008), but it also stores the reference to the original invoice. This cross-referencing is automatic when the original invoice ID is included in the JSON payload. The generated credit note PDF displays both numbers prominently, making the paper trail immediately clear to anyone reviewing the documents later, whether that is the buyer's accounts payable department, an external auditor, or the business owner trying to reconcile the books six months down the line.

Why This Became More Than a Personal Fix

What started as a solution to a personal invoicing headache turned into something considerably broader when it became clear that the problem was universal. Every freelancer, every small agency, every solo founder running multiple ventures faces some version of the same challenge. The existing tools are either too complex (full accounting suites that require weeks of setup and ongoing maintenance) or too simple (free invoice templates that are essentially glorified Word documents with no automation whatsoever). The middle ground, a tool that is powerful enough to handle multiple companies and document types but simple enough to integrate with a single API call, simply did not exist.

The API sits in that middle ground by design. It does not try to be an accounting system. It does not track payments, manage expenses, or reconcile bank statements. It does exactly one thing: transform structured data into professionally formatted financial documents. That narrow focus is what makes it reliable and what makes it composable with whatever other systems a business already uses. Pipe data from Notion, from Airtable, from a custom CRM, from a Shopify webhook, from a cron job that reads a database. The API does not care where the data comes from. It cares that the data is valid JSON with the required fields, and it returns a PDF that is ready to send.

The plan going forward involves building a full invoicing SaaS application on top of this API, complete with a dashboard for managing companies, clients, and document history. But the API will remain the foundation, because the lesson learned from years of frustration with other tools is that the interface should never be the bottleneck. When the data is ready, the document should be ready. No clicking through forms, no selecting dropdown values that the system already knows, no waiting for a page to load so a "Generate PDF" button can be pressed. JSON in, PDF out, invoice done.

Frequently Asked Questions

What document types can the invoicing API generate?

The API generates five distinct document types from JSON input: standard invoices, proforma invoices, credit notes, debit notes, and receipts. Each type follows proper legal formatting conventions and supports auto-numbering, cross-referencing between related documents, and full customization of branding and layout. All five types are accessible through the same API endpoint family with minimal variation in the JSON payload structure.

How does auto-numbering work across multiple companies?

Each company maintains independent numbering sequences for each document type. The format is configurable per company, supporting patterns like simple numeric (001), year-prefixed (2026-001), or company-coded (ABC-INV-001). The counter increments automatically on the server with every generated document, eliminating the risk of duplicates or gaps. This is particularly important in jurisdictions where sequential invoice numbering is a legal requirement subject to audit.

Can the API generate invoices in different currencies?

Yes. The currency is specified in the JSON payload along with all other document parameters. The API formats amounts according to the conventions of the specified currency, including the correct symbol, decimal separator, and thousands grouping. Multi-currency support is essential for businesses that invoice international clients, and it works the same way across all five document types.

Is a proforma invoice legally binding?

A proforma invoice is not a tax document and does not carry the same legal weight as a standard invoice. It serves as a formal quotation or prepayment request. It is commonly used in international trade for customs purposes and by freelancers to request deposits. The API marks proforma invoices clearly in their header and adjusts the payment terms language so there is no ambiguity about the document's legal status.

How does the credit note reference the original invoice?

When generating a credit note, the JSON payload includes the original invoice's reference number. The API automatically displays this reference prominently on the generated PDF, creating a clear audit trail between the original transaction and the correction. The same referencing mechanism applies to debit notes, ensuring that every corrective document is explicitly linked to the document it modifies.

Can this replace QuickBooks or FreshBooks for invoicing?

The API replaces the document generation component of those tools but does not attempt to replace their full accounting functionality. It does not track payments, manage expenses, or handle bank reconciliation. For businesses that need a complete accounting suite, QuickBooks and similar tools remain appropriate. For businesses that already have their financial data organized and simply need a fast, reliable way to turn that data into professional PDFs, the API is a more focused and more flexible solution.