API reference

Invoice

A bill to a customer. A draft isn't in the books yet; once sent it's owed (Accounts Receivable) until paid. The API makes invoices; emailing them is done in TallyPip.

The invoice object

object string
Always "invoice".
id id
The invoice's id (a UUID). Use it to fetch it, or to refer to it from other things.
number string
The invoice number (the next one unless one was given).
customer_id id
Who it's for.
project_id id or null
The customer's project it belongs to, if any.
location_id id or null
Its location (Locations), if any.
status string
draft, sent (in the books and owing), paid or void.
issue_date date
The invoice date.
due_date date
When it's due.
terms string
due_on_receipt, net_7, net_15, net_30, net_60 or custom.
currency string
Its currency: the business's (USD or CAD), or the customer's or vendor's when they're in another currency (Multicurrency, like EUR). All its _cents amounts are in it.
exchange_rate string or null
In another currency: what 1 unit of it was worth in the business's currency, as a decimal ("0.73215"). Null otherwise.
subtotal_cents integer
The lines added up.
discount_cents integer
Discount off the whole invoice, before tax.
tax_rate number
The standard sales tax rate for taxable lines, as a percentage (8.875).
tax_cents integer
Sales tax.
late_fee_cents integer
A late fee added once it was overdue (0 if none); included in total_cents.
total_cents integer
The total.
paid_cents integer
Paid so far (payments and credits).
balance_cents integer
Still owing (0 when paid or void).
po_number string or null
The customer's purchase order number.
summary string or null
A one-line summary under the title (like the project).
message string or null
The message on the invoice.
footer string or null
The footer.
sent_at timestamp or null
When it was sent.
voided_at timestamp or null
When it was voided.
created_at timestamp
When it was added, in UTC.
updated_at timestamp
When it last changed.
lines list
Only when fetching one invoice (not in lists). Each line: id, product_id, description, quantity, rate_cents (price for 1), amount_cents, taxable, tax_rate (its own rate, or null for the standard rate), tax_rate_id, income_account_id, class_id (its class, or null).

Example

{
  "object": "invoice",
  "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708104",
  "number": "INV-1042",
  "customer_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708101",
  "project_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708108",
  "location_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
  "status": "sent",
  "issue_date": "2026-10-06",
  "due_date": "2026-11-05",
  "terms": "net_30",
  "currency": "USD",
  "exchange_rate": null,
  "subtotal_cents": 24000,
  "discount_cents": 0,
  "tax_rate": 0,
  "tax_cents": 0,
  "late_fee_cents": 0,
  "total_cents": 24000,
  "paid_cents": 0,
  "balance_cents": 24000,
  "po_number": null,
  "summary": null,
  "message": "Thank you for your business.",
  "footer": null,
  "sent_at": "2026-10-06T14:30:00.000Z",
  "voided_at": null,
  "created_at": "2026-10-06T14:30:00.000Z",
  "updated_at": "2026-10-06T14:30:00.000Z",
  "lines": [
    {
      "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708140",
      "product_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708103",
      "description": "Standard cleaning visit",
      "quantity": 2,
      "rate_cents": 12000,
      "amount_cents": 24000,
      "taxable": false,
      "tax_rate": null,
      "tax_rate_id": null,
      "income_account_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708131",
      "class_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708190"
    }
  ]
}

List invoices

GET /api/v1/invoices

Invoices, newest first (without their lines).

Key: any (Read only works).

Query

limit integer
How many, 1 to 100 (default 25).
starting_after id
The last id of the page before, for the next page (when has_more is true).
filters
customer_id, status (draft, sent, paid, void), number

Newest first. Answers a list: { object: "list", url, has_more, data }.

Request

curl https://tallypip.com/api/v1/invoices?limit=3 \
  -H "Authorization: Bearer tpk_your_key"

Answer: 200

{
  "object": "list",
  "url": "/api/v1/invoices",
  "has_more": false,
  "data": [
    {
      "object": "invoice",
      "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708104",
      "number": "INV-1042",
      "customer_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708101",
      "project_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708108",
      "location_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
      "status": "sent",
      "issue_date": "2026-10-06",
      "due_date": "2026-11-05",
      "terms": "net_30",
      "currency": "USD",
      "exchange_rate": null,
      "subtotal_cents": 24000,
      "discount_cents": 0,
      "tax_rate": 0,
      "tax_cents": 0,
      "late_fee_cents": 0,
      "total_cents": 24000,
      "paid_cents": 0,
      "balance_cents": 24000,
      "po_number": null,
      "summary": null,
      "message": "Thank you for your business.",
      "footer": null,
      "sent_at": "2026-10-06T14:30:00.000Z",
      "voided_at": null,
      "created_at": "2026-10-06T14:30:00.000Z",
      "updated_at": "2026-10-06T14:30:00.000Z",
      "lines": [
        {
          "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708140",
          "product_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708103",
          "description": "Standard cleaning visit",
          "quantity": 2,
          "rate_cents": 12000,
          "amount_cents": 24000,
          "taxable": false,
          "tax_rate": null,
          "tax_rate_id": null,
          "income_account_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708131",
          "class_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708190"
        }
      ]
    }
  ]
}

Try it

With your own key (Settings › Connected apps). It stays in this page only, and reading can't change anything.

Create an invoice

POST /api/v1/invoices

Make an invoice: a draft, or sent (in the books and owing). It isn't emailed.

Key: Read and change.

Body (JSON)

customer_id id
Required.
project_id id
Optional. One of the customer's projects that isn't completed or canceled.
location_id id
Optional. An active location from /locations.
lines list
Required, 1 to 200. Each: description and rate_cents (its price for 1), or product_id (which brings its description, price, tax and income account); quantity (default 1); taxable; tax_rate_id or tax_rate; income_account_id; class_id (an active class from /classes).
status string
draft (the default) or sent: in the books and owing. Emailing it is done in TallyPip.
issue_date date
Default: today.
terms, due_date string, date
Default: the customer's terms, else the business's. A due_date alone means custom terms.
number string
Default: the next number.
tax_rate number
The standard rate for taxable lines, as a percentage. Default: the business's.
discount_percent or discount_cents number, integer
Optional, off the whole invoice before tax.
po_number, summary, message, footer string
Optional.

Answers 201 with the new invoice. Refused with 400 and the reason (nothing is saved); send an Idempotency-Key so a retry can't make it twice.

Request

curl https://tallypip.com/api/v1/invoices \
  -H "Authorization: Bearer tpk_your_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: <a new id for each change>" \
  -d '{
    "customer_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708101",
    "project_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708108",
    "location_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
    "status": "sent",
    "lines": [
      {
        "product_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708103",
        "quantity": 2,
        "class_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708190"
      }
    ],
    "message": "Thank you for your business."
  }'

Answer: 201

{
  "object": "invoice",
  "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708104",
  "number": "INV-1042",
  "customer_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708101",
  "project_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708108",
  "location_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
  "status": "sent",
  "issue_date": "2026-10-06",
  "due_date": "2026-11-05",
  "terms": "net_30",
  "currency": "USD",
  "exchange_rate": null,
  "subtotal_cents": 24000,
  "discount_cents": 0,
  "tax_rate": 0,
  "tax_cents": 0,
  "late_fee_cents": 0,
  "total_cents": 24000,
  "paid_cents": 0,
  "balance_cents": 24000,
  "po_number": null,
  "summary": null,
  "message": "Thank you for your business.",
  "footer": null,
  "sent_at": "2026-10-06T14:30:00.000Z",
  "voided_at": null,
  "created_at": "2026-10-06T14:30:00.000Z",
  "updated_at": "2026-10-06T14:30:00.000Z",
  "lines": [
    {
      "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708140",
      "product_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708103",
      "description": "Standard cleaning visit",
      "quantity": 2,
      "rate_cents": 12000,
      "amount_cents": 24000,
      "taxable": false,
      "tax_rate": null,
      "tax_rate_id": null,
      "income_account_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708131",
      "class_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708190"
    }
  ]
}

Retrieve an invoice

GET /api/v1/invoices/{id}

One invoice with its lines.

Key: any (Read only works).

Request

curl https://tallypip.com/api/v1/invoices/3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708104 \
  -H "Authorization: Bearer tpk_your_key"

Answer: 200

{
  "object": "invoice",
  "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708104",
  "number": "INV-1042",
  "customer_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708101",
  "project_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708108",
  "location_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
  "status": "sent",
  "issue_date": "2026-10-06",
  "due_date": "2026-11-05",
  "terms": "net_30",
  "currency": "USD",
  "exchange_rate": null,
  "subtotal_cents": 24000,
  "discount_cents": 0,
  "tax_rate": 0,
  "tax_cents": 0,
  "late_fee_cents": 0,
  "total_cents": 24000,
  "paid_cents": 0,
  "balance_cents": 24000,
  "po_number": null,
  "summary": null,
  "message": "Thank you for your business.",
  "footer": null,
  "sent_at": "2026-10-06T14:30:00.000Z",
  "voided_at": null,
  "created_at": "2026-10-06T14:30:00.000Z",
  "updated_at": "2026-10-06T14:30:00.000Z",
  "lines": [
    {
      "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708140",
      "product_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708103",
      "description": "Standard cleaning visit",
      "quantity": 2,
      "rate_cents": 12000,
      "amount_cents": 24000,
      "taxable": false,
      "tax_rate": null,
      "tax_rate_id": null,
      "income_account_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708131",
      "class_id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708190"
    }
  ]
}

Try it

With your own key (Settings › Connected apps). It stays in this page only, and reading can't change anything.