Skip to content

Pagination

The VRP Billing API uses cursor-based pagination for collection endpoints. Each response returns the items under results along with cursors that allow you to request the next or previous slice of data.

Response Format

{
  "results": [
    {"id": "mandate_f9d3", ...},
    {"id": "mandate_k1l2", ...}
  ],
  "next_cursor": "cD0yMDI0LTEyLTMxVDA5OjAwOjAwLjAwMDAwMFo7aWQ9MTIz",
  "previous_cursor": null,
  "page_size": 50
}
  • next_cursor – pass this value to the cursor query parameter to fetch the next page.
  • previous_cursor – pass to cursor to page backwards. When null, there is no previous page available.
  • page_size – the number of records returned for this page.

Cursors are opaque strings. Do not attempt to parse or modify them.

Requesting Additional Pages

GET /payments?cursor=cD0yMDI0LTEyLTMxVDA5OjAwOjAwLjAwMDAwMFo7aWQ9MTIz&page_size=25
  • page_size defaults to 50 and is capped at 200.
  • Supplying cursor resumes from the next or previous location returned by the API.

Sorting

Use the order parameter to control ordering:

  • order=-created_at (default) – newest first.
  • order=created_at – oldest first.
  • order=amount_minor – ascending by amount, then by creation time.
  • order=-amount_minor – descending by amount.

Only the fields listed above are accepted. Any other value returns a validation error.

Filtering

Collection endpoints share a common filter syntax:

  • created_at[gte] / created_at[lte] – filter by creation timestamp.
  • status – filter by resource status (case-insensitive).
  • merchant_id – must match the authenticated merchant identifier.
  • amount[gte] / amount[lte] – filter by amount in minor units when applicable.

Refer to the specific endpoint documentation for additional filters (for example, payment_id on the payments endpoint).

Backfilling Historical Data

To retrieve historical records:

  1. Start without cursor to fetch the most recent page.
  2. Continue requesting pages using the returned next_cursor until it becomes null.
  3. Store the last cursor fetched so you can resume if interrupted.

Real-time Synchronisation

For near real-time sync, poll the list endpoint with a created_at[gte] filter and reuse the returned next_cursor to continue from the last processed record. Combine this strategy with webhooks for low-latency updates.

Error Handling

  • Requests with an expired cursor return 400 with code invalid_cursor.
  • Page sizes exceeding 200 return 400 with code page_size_too_large.
  • Unsupported order values return 400 with code invalid_order.

Examples

Python example for iterating through all mandates:

import requests


def list_all_mandates(session, params=None):
    params = dict(params or {})
    url = "https://api.vrpbilling.com/v1/mandates"
    cursor = None
    while True:
        if cursor:
            params["cursor"] = cursor
        response = session.get(url, params=params)
        response.raise_for_status()
        payload = response.json()
        for mandate in payload["results"]:
            yield mandate
        cursor = payload.get("next_cursor")
        if not cursor:
            break

This approach ensures efficient pagination while handling rate limits and retries using your session configuration.