Skip to content

Pagination

List endpoints return 25 records by default, up to 100, and page with an opaque cursor.

{
"object": "list",
"data": [ /* up to `limit` objects */ ],
"has_more": true,
"next_cursor": "MjAyNi0wNy0xOVQxMjowNDoxMS4wMDBa"
}
  • data — the resources, sorted by created_at descending (newest first) on every paginated endpoint.
  • has_moretrue when more records exist beyond this page.
  • next_cursor — an opaque string to pass as cursor on the next request. It is null whenever has_more is false.
NameTypeDefaultNotes
limitinteger25Clamped to a maximum of 100. A value that is non-numeric, zero, or negative falls back to 25.
cursorstringnullThe next_cursor from the previous page.
Terminal window
curl "https://app.nativpost.com/api/v1/content?limit=25" \
-H "Authorization: Bearer $NATIVPOST_API_KEY"

Then follow the cursor:

Terminal window
curl "https://app.nativpost.com/api/v1/content?limit=25&cursor=MjAyNi0wNy0xOVQxMjowNDoxMS4wMDBa" \
-H "Authorization: Bearer $NATIVPOST_API_KEY"

Continue until has_more is false.

next_cursor encodes the created_at timestamp of the last record on the page, not its id. Treat it as opaque — read it from a response and hand it straight back. Do not construct one from a record id, and do not assume it stays a fixed length or format.

Because paging is by timestamp with a strict comparison, two records sharing an identical created_at on a page boundary can cause one to be skipped. This is rare in practice, and only affects records created in the same millisecond.

A cursor that is malformed, truncated, or decodes to something that is not a date does not return an error. It is silently dropped and you get the first page back. There is no 400 for a bad cursor, and cursors do not expire — one saved a month ago still works, as long as you kept it verbatim.

The practical consequence: if a paging loop appears to restart from the top, suspect a corrupted cursor rather than a server error. Compare the first id of the new page against the previous page’s ids and stop if they repeat.

Filters such as status on /content or asset_type on /media-library are independent of the cursor. Pass the same filter values on every request in the sequence — dropping one mid-loop silently widens the result set.

Cursor pagination is supported on:

  • GET /api/v1/content
  • GET /api/v1/campaigns
  • GET /api/v1/media-library
  • GET /api/v1/templates

GET /api/v1/social-accounts and GET /api/v1/webhooks return the full set in one response. They use the same envelope for consistency, but always report has_more: false and next_cursor: null, and they ignore limit and cursor.