List Customers API
Use this endpoint to retrieve a paginated list of the partner's customers, including their current link state.
URL path - /billing/sites/{siteId}/customers
Method - GET
Overview
Returns customers the partner has previously invited. Each item indicates the current link state and the relevant timestamps. Results are ordered by invitedAt descending (most recently invited first).
Pagination is link-based. Each response includes pre-formed pagination URLs as nextHref (more results forward) and prevHref (results backward), which the partner follows directly with the same Authorization and Pyng-Api-Version headers. Partners do not construct pagination URLs themselves — they treat the href values as opaque.
Both fields are optional. On the first page, prevHref is omitted. On the last page, nextHref is omitted. When neither is present, the entire result set fits in a single response. An empty items array combined with no nextHref indicates a filtered result with nothing to return, not an error.
Request Headers
| Header Name | Header Value | Notes |
|---|---|---|
| Authorization | Bearer access_token | Access token must include scope billing:customers:read |
| Pyng-Api-Version | urn:pyng:api:billing:version:v1 | Required. See API Versions. |
Path Parameters
| Parameter Key | Parameter Data Type | Notes |
|---|---|---|
| siteId | string | Unique identifier of the Site whose customers to list. The Site must belong to the calling Organisation. |
Query Parameters
Filter parameters are supplied on the first request. Subsequent pages are reached by following nextHref / prevHref from the previous response — those URLs already encode the original filters and the pagination position.
| Parameter Key | Parameter Data Type | Required | Notes |
|---|---|---|---|
| limit | integer | N | Maximum number of items to return. Allowed range 1–100. Default 50. |
| state | string | N | Filter by current link state. One of LinkState. Omit to return all states. |
| invitedFrom | integer | N | Lower bound, inclusive. Unix timestamp in milliseconds. Returns only customers with invitedAt >= invitedFrom. |
| invitedTo | integer | N | Upper bound, inclusive. Unix timestamp in milliseconds. Returns only customers with invitedAt <= invitedTo. |
Response
Status Code - 200 OK
| Parameter Key | Parameter Data Type | Required | Notes |
|---|---|---|---|
| data | object | Y | object of CustomerListResponse type |
| traceId | string | Y | Unique identifier of the request |
CustomerListResponse
| Parameter Key | Parameter Data Type | Required | Notes |
|---|---|---|---|
| items | array | Y | Page of customers. See CustomerSummary. May be empty. |
| totalItems | integer | Y | Total number of customers matching the current state, invitedFrom, and invitedTo filters. Independent of limit. Returned on every page. |
| nextHref | string | N | Pre-formed URL for the next page. Treat as opaque. Omitted on the last page. |
| prevHref | string | N | Pre-formed URL for the previous page. Treat as opaque. Omitted on the first page. |
CustomerSummary
| Parameter Key | Parameter Data Type | Required | Notes |
|---|---|---|---|
| customerReference | string | Y | Partner-supplied identifier for the customer |
| state | string | Y | One of LinkState |
| invitedAt | integer | Y | Unix timestamp in milliseconds, when the invitation was minted |
| expiresAt | integer | N | Unix timestamp in milliseconds, when the invitation expires. Present only when state is invited. |
| linkedAt | integer | N | Unix timestamp in milliseconds, when the customer completed Pyng signup. Present only when state is linked. |
Examples
Request — First Page
GET /billing/sites/{siteId}/customers?limit=2 HTTP/1.1
Host: sample.pyng.com.au
Authorization: Bearer access_token
Pyng-Api-Version: urn:pyng:api:billing:version:v1
Response — First Page
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"data": {
"items": [
{
"customerReference": "ACME-002",
"state": "invited",
"invitedAt": 1777852800000,
"expiresAt": 1778457600000
},
{
"customerReference": "ACME-001",
"state": "linked",
"invitedAt": 1777680000000,
"linkedAt": 1777683600000
}
],
"totalItems": 3,
"nextHref": "https://sample.pyng.com.au/billing/sites/{siteId}/customers?limit=2&cursor=eyJ2IjoxLCJrIjoieFFwM21KOEx2VHl3In0%3D"
},
"traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}
Request — Next Page
The partner follows the nextHref URL from the previous response, supplying the same Authorization and Pyng-Api-Version headers.
GET /billing/sites/{siteId}/customers?limit=2&cursor=eyJ2IjoxLCJrIjoieFFwM21KOEx2VHl3In0%3D HTTP/1.1
Host: sample.pyng.com.au
Authorization: Bearer access_token
Pyng-Api-Version: urn:pyng:api:billing:version:v1
Response — Last Page
The nextHref field is omitted, signalling the end of the list. The partner stops paging forward. prevHref is present so the partner can navigate back if needed.
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"data": {
"items": [
{
"customerReference": "ACME-000",
"state": "linked",
"invitedAt": 1776729600000,
"linkedAt": 1776816000000
}
],
"totalItems": 3,
"prevHref": "https://sample.pyng.com.au/billing/sites/{siteId}/customers?limit=2&cursor=eyJ2IjoxLCJrIjoiYUg4eFJxNG5HVndsIiwiZCI6InByZXYifQ%3D%3D"
},
"traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}
Request — Filter by State
GET /billing/sites/{siteId}/customers?state=invited&limit=50 HTTP/1.1
Host: sample.pyng.com.au
Authorization: Bearer access_token
Pyng-Api-Version: urn:pyng:api:billing:version:v1
Request — Filter by Invitation Date Range
Returns customers invited between 2026-05-01 00:00:00 UTC (1777593600000) and 2026-05-04 23:59:59 UTC (1777939199000), inclusive.
GET /billing/sites/{siteId}/customers?invitedFrom=1777593600000&invitedTo=1777939199000 HTTP/1.1
Host: sample.pyng.com.au
Authorization: Bearer access_token
Pyng-Api-Version: urn:pyng:api:billing:version:v1
Error Response — Invalid Pagination Link
Returned if the partner follows a tampered, expired, or otherwise invalid nextHref/prevHref.
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
{
"errors": [
{
"code": "urn:pyng:platform:billing:error:customers:invalid-pagination-link",
"displayMessage": "The pagination link is not valid. Restart pagination from the first page.",
"target": "nextHref"
}
],
"traceId": "9ae2e340-b983-4274-b400-c974a9ab40ab"
}