xPlantAPI

Pagination

Every list pages by cursor. Pass meta.next_cursor back as cursor until it's null.

List endpoints return one page at a time. data is a plain array, and there's no total count.

Page with the cursor

Every list response carries meta.next_cursor. Pass it back unchanged as cursor, with the same filters, to get the next page. It's null on the last page.

{ "ok": true, "data": [ … ], "meta": { "next_cursor": "eyJ…" } }
curl "https://app.xplantpro.com/api/v1/plants?limit=200" \
  -H "Authorization: Bearer $XPLANT_API_KEY"
# then the same request with &cursor=<meta.next_cursor>, until next_cursor is null
  • Treat the cursor as opaque: don't parse it, build it or store it for long.
  • Keep the same filters and limit for every page of one walk.
  • A cursor that has expired or no longer applies answers 422 INVALID_CURSOR: start again from the first page.
  • cursor can't be combined with an offset above 0; that answers 422.

A cursor picks up exactly where the last page ended, so records created while you're paging don't shift what you see.

Page size

Listlimit defaultlimit maximum
Most lists50200
Sensor readings1001,000
Devices and device tokens200200

Values above the maximum are capped. A missing, zero, negative or non-numeric limit falls back to the default.

In code

The SDK's list methods follow the cursor for you. Awaiting a list gives you one page; iterating it gives you every row:

import { XPlantClient } from "@shmaplex/xplant-sdk";

const client = new XPlantClient({ apiKey: process.env.XPLANT_API_KEY });

// One page, as an array.
const firstPage = await client.plants.list({ limit: 200 });

// Every row, fetched a page at a time as you go.
for await (const plant of client.plants.list()) {
  console.log(plant.id);
}

// Page by page, with a cursor you can save and resume from later.
for await (const { data, nextCursor, hasMore } of client.explants.list().pages()) {
  await save(data, nextCursor);
}
const resumed = await client.explants.list({ cursor: savedCursor });

// Filters go in the same object:
for await (const event of client.events.list({ entity: "explant" })) {
  // …
}

Sensor readings

GET /sensor-readings returns readings newest first. Narrow the window with since and until (both inclusive; a since later than until answers 422), then page through it with the cursor like any other list.

Offset

Lists still accept offset (records to skip) for older integrations, but offsets count records at the moment you ask: a record added ahead of your position shifts the next page, so you can see one twice or miss one. Use the cursor for anything new. To keep a mirror exact, sync from change history with since.

Edit on GitHub

On this page