Pagination and filtering
How list endpoints page their results with limit and offset or with page numbers, and how to read the total.
List endpoints answer one page of results at a time. Each list takes one of four sets of paging parameters, and many take filters as well. The API reference gives the parameters of every route. This page lists the conventions, the page sizes of the main lists, and how to read a total.
Paging parameters
Section titled Paging parameters| Parameters | First page | Next page | Used by |
|---|---|---|---|
limit and offset |
offset=0 |
Add limit to offset. |
GET /services/ and GET /payments/disputes in the Client API, and most lists in the Organization API, the Commerce API and the Store API |
page and limit |
page=1 |
Add 1 to page. |
Invoices, transactions, a service's events and support conversations in the Client API |
page and per_page |
page=1 |
Add 1 to page. |
DNS zones and records, proxy routes, SSL certificates and products in the Client API, and services in the customer portal |
before_id and limit |
Leave out before_id. |
Send the last answer's next_before_id as before_id. |
Events, promotions, gift cards and fulfilment provider logs in the Commerce API |
page starts at 1, and page n skips the first (n - 1) × limit results (or (n - 1) × per_page). A page past the last one answers an empty list.
Lists come newest first unless the tables below say otherwise. Invoices, transactions, customers and Commerce orders break a tie on the ID, so while nothing changes, every row appears on exactly one page. On a list sorted newest first, a row added while you page pushes the others down by one, and the next page then starts with the last row of the page before. Skip IDs you already hold.
Page sizes
Section titled Page sizesLeave out limit or per_page to get the default. On most lists, a value above the largest size, or below 1, answers 422, and the entry in detail names the parameter and the largest size:
{
"detail": [
{
"type": "less_than_equal",
"loc": ["query", "limit"],
"msg": "Input should be less than or equal to 200",
"input": "500",
"ctx": {"le": 200}
}
]
}
Client API
Section titled Client API| List | Route | Paging | Default | Largest |
|---|---|---|---|---|
| Services | GET /services/ |
limit, offset |
100 | 500 |
| A service's events | GET /services/{service_ref}/events |
page, limit |
50 | 200 |
| Invoices | GET /billing/invoices |
page, limit |
50 | 200 |
| Transactions | GET /billing/transactions |
page, limit |
50 | 200 |
| Disputes | GET /payments/disputes |
limit, offset |
50 | 100 |
| DNS zones, in order of domain | GET /dns/zones |
page, per_page |
25 | 100 |
| A zone's records, in order of name, then type | GET /dns/zones/{zone_id}/records |
page, per_page |
100 | 1,000 |
| Proxy routes | GET /proxy/routes |
page, per_page |
50 | 200 |
| SSL certificates | GET /ssl/certificates |
page, per_page |
25 | 100 |
| Products, in the order the catalogue shows them | GET /products/ |
page, per_page |
100 | 200 |
| Support conversations, latest activity first | GET /chat/conversations |
page, limit |
20 | 100 |
| Messages in a conversation, oldest first | GET /chat/conversations/{conversation_id}/messages |
before_id, after_id, limit |
50 | 100 |
GET /billing/crypto/deposits takes limit alone (50 by default, at most 200) and answers the newest deposits, with no way to ask for older ones.
Organization API and customer portal
Section titled Organization API and customer portal| List | Route | Paging | Default | Largest |
|---|---|---|---|---|
| Customers | GET /orgs/{org_slug}/customers |
limit, offset |
50 | 200 |
| Invoices | GET /orgs/{org_slug}/invoices |
limit, offset |
50 | 500, cut down |
| Audit log | GET /orgs/{org_slug}/audit-log |
limit, offset |
50 | 200 |
| A customer's services | GET /orgs/{org_slug}/portal/services |
page, per_page |
50 | 200 |
| A customer's invoices | GET /orgs/{org_slug}/portal/invoices |
limit, offset |
50 | 500, cut down |
| A customer's transactions | GET /orgs/{org_slug}/portal/transactions |
limit, offset |
50 | 500, cut down |
Where the table says cut down, a larger limit does not fail: the list answers 500 results instead.
Commerce API and Store API
Section titled Commerce API and Store API| List | Route | Paging | Default | Largest |
|---|---|---|---|---|
| Orders | GET /orgs/{org_slug}/commerce/orders |
limit, offset |
50 | 200 |
| Products, most recently changed first | GET /orgs/{org_slug}/commerce/products |
limit, offset |
50 | 200 |
| Events | GET /orgs/{org_slug}/commerce/events |
before_id, limit |
50 | 200 |
| Promotions | GET /orgs/{org_slug}/commerce/promotions |
before_id, limit |
50 | 200 |
| Gift cards | GET /orgs/{org_slug}/commerce/gift-cards |
before_id, limit |
50 | 200 |
| Store products | GET /orgs/{org_slug}/store/products |
limit, offset |
20 | 100 |
| Store collections, in the store's order | GET /orgs/{org_slug}/store/collections |
limit, offset |
50 | 100 |
Store products come newest first by default. order changes that: -created_at, created_at, -title or title.
Totals
Section titled TotalsMost lists answer a bare JSON array with no total. Those below say how many results match.
| Lists | How to get the total | Answer |
|---|---|---|
| Invoices and transactions in the Client API | Add with_total=true. |
{"items": [...], "total": 12, "page": 1, "limit": 50, "counts": {...}} |
| Customers and invoices in the Organization API, and invoices and transactions in the customer portal | Add with_total=true. |
{"items": [...], "total": 12, "limit": 50, "offset": 0, "counts": {...}} |
| Proxy routes | Always there. | {"routes": [...], "total": 12, "page": 1, "per_page": 50} |
| SSL certificates | Always there. | {"certificates": [...], "total": 12} |
Lists in the Commerce API and the Store API that take offset |
Always there. | The results under a name such as orders, with count, limit and offset |
total and count are the number of results the filters match, across every page. counts gives the number for each status or type as if no status or type filter were set, with all for the whole list. Invoices add open, which is unpaid and overdue together, and Client API transactions add credit, which is credit added and credit used together. Organization invoices also carry outstanding: what the open invoices owe, for each currency.
Filters
Section titled FiltersA filter narrows the list before it is cut into pages, so total and every page reflect it. A filter the route does not know is ignored.
| Filter | Lists | What it matches |
|---|---|---|
status |
Services | One status: pending, provisioning, active, suspended, pending_termination, terminated or failed. |
resource_type |
Services | vps (or cloud_compute), container, ip (or floating_ip), mail or smtp_relay. Another word answers 422 with "error": "invalid_resource_type" and the accepted words in allowed. |
tag |
Services | Services with that tag. |
status_filter |
Invoices | open, draft, unpaid, paid, cancelled, refunded or overdue. |
type_filter |
Transactions | payment, refund, credit, credit_add or credit_deduct. In the customer portal: payment, refund, chargeback, credit_add or credit_deduct. |
record_type and name |
A zone's records | One record type, in any case, and one exact record name. |
status, priority and q |
Support conversations | status takes open, awaiting_customer, awaiting_agent, in_progress, on_hold or closed, and open matches every conversation that is not closed. priority takes low, medium, high or critical. q searches the subject and the latest message, and # followed by a number finds that conversation. |
q |
Organization customers, portal invoices and Commerce orders | Search text: a customer's email, name, handle, company or number; an invoice number; or an order number such as #1001, an order ID or part of an email. |
placed_from and placed_to |
Commerce orders | A date and time range. placed_to itself is left out. |
resource_type, type_filter, priority and the Client API's status_filter answer 422 for a word they do not list. The other filters match nothing when no result has the value you send. The reference for each route lists the rest of its filters.
Walk every page
Section titled Walk every pageAsk for pages until one holds fewer results than you asked for, or until you have total results. This reads every service, 100 at a time:
offset=0
while :; do
page=$(curl -s "https://api.coritan.com/api/v1/services/?limit=100&offset=$offset" \
-H "Authorization: Bearer $CORITAN_TOKEN")
echo "$page" | jq -c '.[]'
[ "$(echo "$page" | jq length)" -lt 100 ] && break
offset=$((offset + 100))
done
On a list that uses before_id, stop when next_before_id is null.
Read new messages
Section titled Read new messagesMessages in a support conversation page by ID rather than by position:
- No parameters
- The latest
limitmessages, oldest first. before_id- The latest
limitmessages older than that message ID, oldest first. Send the ID of the first message you hold to read further back. after_id- Up to
limitmessages newer than that message ID, oldest first. Send the ID of the last message you hold to fetch only what is new.
Internal notes from Coritan's team never appear in the list. Poll no more often than you need to: Rate limits applies to every request.
When you poll GET /orgs/{org_slug}/portal/services for changes, add consistency=eventual. The answer may miss a change made a moment ago, so leave it out on the first read after a change of your own.