API essentials

Pagination and filtering

Page through any list with cursors, filter it with one field[operator]=value grammar, and sort or search it. There is no catch-all filter parameter to guess.

Lists that grow with your customer volume page with cursors, and you filter them with one field[operator]=value grammar. Code that pages and filters one list works for the others.

Read a list response

Every list that grows with your customer volume is cursor-paginated and returns the same shape:

{
  "object": "list",
  "data": [ … ],
  "has_more": true,
  "next_cursor": "k:inv_9f2c…",
  "total": 1284
}

Page through a list

Pass next_cursor back as starting_after:

curl "$TMBILLING_URL/v1/businesses/$BIZ/invoices?limit=50" \
  -H "Authorization: Bearer $TMBILLING_API_KEY"

curl "$TMBILLING_URL/v1/businesses/$BIZ/invoices?limit=50&starting_after=k:inv_9f2c…" \
  -H "Authorization: Bearer $TMBILLING_API_KEY"

limit defaults to 50 and caps at 1000. Treat next_cursor as opaque — it encodes how tmbilling is walking the current sort, so parsing it breaks when the sort changes.

has_more: false means the end of the list. A page can be shorter than limit and still not be the last one.

Filter a list

Write filters as field[operator]=value:

?created_at[after]=2026-09-01&status[in]=paid,posted

There is no generic filters parameter. Each filterable field is its own documented query parameter, and any query key that is neither a filter nor a documented parameter returns 400. So a misspelled filter tells you, rather than quietly returning an unfiltered list.

Select an operator

Field typeOperators
Textis, is_not, contains, not_contains, starts_with, ends_with, is_present
Enumis, is_not, in, not_in, is_present
Booleanis
Numberis, is_not, gt, gte, lt, lte, between, is_present
Dateon, before, after, between, in_last, in_next, is_present

Most operators take one scalar. Four take something else:

OperatorValueExample
in, not_ina comma-separated setstatus[in]=paid,posted matches any member
betweenexactly two valuestotal[between]=1000,5000, both ends inclusive
in_last, in_nexta number of dayscreated_at[in_last]=30 — days, not hours, not an ISO duration
is_presenttrue or falsepo_number[is_present]=false asks whether the field is set

Give dates in ISO-8601. tmbilling resolves day boundaries in the business's timezone rather than UTC, so created_at[on]=2026-09-01 means that calendar day where the business is — the same day the row is labelled with everywhere else.

Sort a list

?sort_by[desc]=created_at
?sort_by[asc]=total

Sort on one field at a time. tmbilling returns newest first by default.

Search a list

Lists that support it take q=<text> and search the fields a person would search by, such as a customer's name and email or an invoice number. Combine it with filters:

curl "$TMBILLING_URL/v1/businesses/$BIZ/customers?q=ada&status[is]=active&limit=20" \
  -H "Authorization: Bearer $TMBILLING_API_KEY"
Copyright © 2026