API Reference

Build integrations with the InvoiceFlow REST API. All requests are made over HTTPS and must include a valid API key. API access requires the Business plan.

Base URL

https://www.invoiceflow.techieszon.com/api/v1

Auth

Bearer token

Format

JSON · REST

Overview

All endpoints are relative to the base URL:

text
https://www.invoiceflow.techieszon.com/api/v1

All responses are JSON. List endpoints return a data array and a meta pagination object:

json
{
  "data": [ ... ],
  "meta": { "total": 42, "page": 1, "pageSize": 20, "totalPages": 3 }
}

Authentication

Generate API keys in Settings → API Keys. Pass your key on every request:

bash
# Option 1 — Authorization header (recommended)
Authorization: Bearer if_live_your_key_here

# Option 2 — X-API-Key header
X-API-Key: if_live_your_key_here

curl example:

bash
curl -H "Authorization: Bearer if_live_your_key_here" \
     https://www.invoiceflow.techieszon.com/api/v1/invoices

JavaScript / TypeScript:

typescript
const res = await fetch("https://www.invoiceflow.techieszon.com/api/v1/invoices", {
  headers: { Authorization: "Bearer if_live_your_key_here" },
});
const { data, meta } = await res.json();
Keep your key secret. It is shown once when generated. Revoke and regenerate it immediately if compromised.

Errors

All errors return a standard JSON body with an error message and a machine-readable code:

json
{ "error": "Not found", "code": "NOT_FOUND" }

Status

Code

Meaning

401UNAUTHORIZEDMissing or invalid API key
403UPGRADE_REQUIREDBusiness plan required
404NOT_FOUNDResource does not exist
400VALIDATION_ERRORInvalid request body
429RATE_LIMITEDToo many requests
500SERVER_ERRORUnexpected server error

Rate Limits

100 requests per minute per API key. Limit status is returned in every response:

http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1717000060000

When exceeded, the API returns 429 RATE_LIMITED. Wait until the reset timestamp before retrying.

Invoices

Invoice statuses: draft · recorded · sent · viewed · partial · paid · overdue · cancelled.recorded invoices are finalized for internal tracking but not sent to the client — they can still be edited and receive payments. Once an invoice moves past draft or recorded it can no longer be edited — only cancelled.
Tax breakdown: When named taxes are configured, taxRate will be "0.00" and the full breakdown is in invoiceTaxLines — an array of { name, type, value, amount } objects. When a flat tax rate is used, taxRate holds the percentage and invoiceTaxLines will be an empty array.
GET
/api/v1/invoices

List all invoices for your organisation

Parameters

pageintegerPage number (default: 1)
page_sizeintegerResults per page, max 100 (default: 20)
statusstringFilter: draft · recorded · sent · viewed · partial · paid · overdue · cancelled
searchstringSearch by invoice number
Response200 OK
{
  "data": [
    {
      "id": "uuid",
      "invoiceNumber": "INV-001",
      "status": "sent",
      "currency": "GHS",
      "subtotal": "1500.00",
      "total": "1500.00",
      "amountPaid": "0.00",
      "balanceDue": "1500.00",
      "issueDate": "2026-05-01T00:00:00Z",
      "dueDate": "2026-05-15T00:00:00Z",
      "clientId": "uuid",
      "createdAt": "2026-05-01T09:00:00Z"
    }
  ],
  "meta": { "total": 42, "page": 1, "pageSize": 20, "totalPages": 3 }
}
GET
/api/v1/invoices/:id

Get a single invoice with items, client, payments, and tax breakdown

Response200 OK
{
  "data": {
    "id": "uuid",
    "invoiceNumber": "INV-001",
    "status": "paid",
    "currency": "GHS",
    "subtotal": "1500.00",
    "discountType": null,
    "discountValue": "0.00",
    "taxRate": "0.00",
    "taxAmount": "225.00",
    "invoiceTaxLines": [
      { "name": "VAT", "type": "percentage", "value": 15, "amount": 225 }
    ],
    "total": "1725.00",
    "amountPaid": "1725.00",
    "balanceDue": "0.00",
    "issueDate": "2026-05-01T00:00:00Z",
    "dueDate": "2026-05-15T00:00:00Z",
    "items": [
      { "description": "Web design", "quantity": "1", "unit": "hrs", "rate": "1500.00", "amount": "1500.00" }
    ],
    "client": { "id": "uuid", "name": "Acme Corp", "email": "billing@acme.com" },
    "payments": [
      { "amount": "1725.00", "paymentMethod": "bank_transfer", "paymentDate": "2026-05-10T00:00:00Z" }
    ]
  }
}
POST
/api/v1/invoices

Create a new draft invoice

Parameters

itemsarrayrequiredLine items: description, quantity, rate, unit (optional)
issueDateISO 8601requiredInvoice issue date
clientIduuidID of the client to bill
currencystring3-letter currency code (default: GHS)
dueDateISO 8601Payment due date
taxRatenumberTax percentage 0–100 (default: 0)
notesstringNotes shown on the invoice
termsstringTerms & conditions text
Response200 OK
{
  "data": { "id": "uuid", "invoiceNumber": "INV-043", "status": "draft", "total": "1500.00" }
}

Clients

GET
/api/v1/clients

List all clients

Parameters

pageintegerPage number (default: 1)
page_sizeintegerResults per page, max 100 (default: 20)
searchstringSearch by name or email
Response200 OK
{
  "data": [
    { "id": "uuid", "name": "Acme Corp", "email": "billing@acme.com", "country": "GH", "createdAt": "2026-01-01T00:00:00Z" }
  ],
  "meta": { "total": 15, "page": 1, "pageSize": 20, "totalPages": 1 }
}
GET
/api/v1/clients/:id

Get a client with their recent invoices

Response200 OK
{
  "data": {
    "id": "uuid",
    "name": "Acme Corp",
    "email": "billing@acme.com",
    "recentInvoices": [
      { "id": "uuid", "invoiceNumber": "INV-001", "status": "paid", "total": "1500.00" }
    ]
  }
}
POST
/api/v1/clients

Create a new client

Parameters

namestringrequiredClient display name
emailemailBilling email address
companystringCompany or business name
phonestringPhone number
countrystringISO 3166-1 alpha-2 country code
currencystringDefault billing currency for this client
Response200 OK
{ "data": { "id": "uuid", "name": "Acme Corp", "createdAt": "2026-05-30T00:00:00Z" } }

Receipts

Receipt statuses: issued · partial · paid_in_full. Receipts are auto-generated when a payment is recorded against an invoice.
GET
/api/v1/receipts

List all payment receipts

Parameters

pageintegerPage number (default: 1)
page_sizeintegerResults per page, max 100 (default: 20)
Response200 OK
{
  "data": [
    {
      "id": "uuid",
      "receiptNumber": "RCP-001",
      "status": "paid_in_full",
      "currency": "GHS",
      "amountReceived": "1500.00",
      "balanceRemaining": "0.00",
      "issueDate": "2026-05-10T00:00:00Z",
      "clientId": "uuid",
      "invoiceId": "uuid",
      "createdAt": "2026-05-10T09:00:00Z"
    }
  ],
  "meta": { "total": 8, "page": 1, "pageSize": 20, "totalPages": 1 }
}
GET
/api/v1/receipts/:id

Get a single receipt with client and payment details

Response200 OK
{
  "data": {
    "id": "uuid",
    "receiptNumber": "RCP-001",
    "amountReceived": "1500.00",
    "client": { "id": "uuid", "name": "Acme Corp" },
    "payments": [{ "amount": "1500.00", "paymentMethod": "bank_transfer" }]
  }
}

Payments

GET
/api/v1/payments

List all payments across all invoices

Parameters

pageintegerPage number (default: 1)
page_sizeintegerResults per page, max 100 (default: 20)
Response200 OK
{
  "data": [
    {
      "id": "uuid",
      "invoiceId": "uuid",
      "amount": "1500.00",
      "currency": "GHS",
      "paymentMethod": "mobile_money",
      "paymentDate": "2026-05-10T00:00:00Z"
    }
  ],
  "meta": { "total": 24, "page": 1, "pageSize": 20, "totalPages": 2 }
}

Webhooks

InvoiceFlow delivers HTTP POST requests to your configured endpoint URL when specific events occur. Set up endpoints in Settings → Webhooks.

Events

invoice.createdA new invoice was created
invoice.sentInvoice was emailed to the client
invoice.viewedClient opened the public invoice link
invoice.paidInvoice is fully paid
invoice.overdueInvoice has passed its due date unpaid
invoice.cancelledInvoice was cancelled by the owner
payment.recordedA payment was recorded on an invoice
client.createdA new client was created

Each request includes X-InvoiceFlow-Signature and X-InvoiceFlow-Event headers. Verify the signature with your webhook secret (shown once when the endpoint is created):

typescript
import { createHmac } from "crypto";

function verifyWebhook(rawBody: string, signature: string, secret: string): boolean {
  const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
  return signature === expected;
}

// Express example
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const sig = req.headers["x-invoiceflow-signature"] as string;

  if (!verifyWebhook(req.body.toString(), sig, process.env.WEBHOOK_SECRET!)) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const { event, data } = JSON.parse(req.body.toString());

  switch (event) {
    case "invoice.paid":
      // Mark order as fulfilled, send thank-you email, etc.
      break;
    case "payment.recorded":
      // Sync to your accounting system
      break;
  }

  res.status(200).json({ received: true });
});
InvoiceFlow retries failed deliveries up to 3 times with exponential back-off. Your endpoint must respond with 2xx within 10 seconds.