Skip to main content
All list endpoints return paginated results using cursor-based pagination. This approach is stable even when items are added or removed between requests.

How it works

Every list response includes pagination metadata:
{
  "object": "list",
  "results": [...],
  "has_more": true,
  "next_cursor": "eyJpZCI6MTIzNH0="
}
FieldTypeDescription
resultsarrayThe page of results.
has_morebooleantrue if there are more results after this page.
next_cursorstring | nullPass this as cursor to get the next page. null when there are no more results.

Paginating through results

To get all items, keep requesting with the cursor parameter until has_more is false:
# First page
curl "https://api.getmatter.com/public/v1/items?limit=50" \
  -H "Authorization: Bearer $MATTER_TOKEN"

# Next page (use next_cursor from previous response)
curl "https://api.getmatter.com/public/v1/items?limit=50&cursor=eyJpZCI6MTIzNH0=" \
  -H "Authorization: Bearer $MATTER_TOKEN"
Python example
import requests

url = "https://api.getmatter.com/public/v1/items"
headers = {"Authorization": f"Bearer {token}"}
params = {"limit": 50}
all_items = []

while True:
    response = requests.get(url, headers=headers, params=params).json()
    all_items.extend(response["results"])

    if not response["has_more"]:
        break
    params["cursor"] = response["next_cursor"]

print(f"Fetched {len(all_items)} items")

Page size

Control page size with the limit parameter:
ParameterDefaultMinMax
limit251100

Incremental sync

Use updated_since to fetch only items that changed after a given timestamp. This is the most efficient way to keep a local copy of your library in sync.
# Get everything changed since your last sync
curl "https://api.getmatter.com/public/v1/items?updated_since=2026-03-29T00:00:00Z" \
  -H "Authorization: Bearer $MATTER_TOKEN"
An item’s updated_at reflects any change to the item or its associated data — status changes, reading progress, favorites, tag additions/removals, new annotations, and content re-extraction all advance the timestamp. For inbox items that have never been interacted with, updated_at is the time the item appeared in your inbox. The updated_since parameter filters by updated_at and works with all other filters (status, tag, etc.). Combine it with pagination to sync large deltas:
Python example
from datetime import datetime

last_sync = "2026-03-29T00:00:00Z"
params = {"updated_since": last_sync, "limit": 100}
changed_items = []

while True:
    response = requests.get(url, headers=headers, params=params).json()
    changed_items.extend(response["results"])
    if not response["has_more"]:
        break
    params["cursor"] = response["next_cursor"]

# Save the current time as your new sync checkpoint
new_sync = datetime.utcnow().isoformat() + "Z"
Store the timestamp before you start syncing. If the sync fails partway through, you can retry from the same checkpoint without missing changes.

Multi-value filters

Several filter parameters accept comma-separated values to match any of the given options:
# Items in queue OR archive
curl "https://api.getmatter.com/public/v1/items?status=queue,archive" \
  -H "Authorization: Bearer $MATTER_TOKEN"

# Articles OR podcasts
curl "https://api.getmatter.com/public/v1/items?content_type=article,podcast" \
  -H "Authorization: Bearer $MATTER_TOKEN"

# Items with any of these tags
curl "https://api.getmatter.com/public/v1/items?tag=tag_n5j2x,tag_k3m9p" \
  -H "Authorization: Bearer $MATTER_TOKEN"
Multi-value filters use OR logic — an item matches if it has any of the specified values.

Ordering

By default, items are ordered by updated_at descending (most recently changed first). This is optimized for incremental sync workflows. You can also request position ordering to get items in the same order shown in the app:
# Queue in manual order (as arranged in the app)
curl "https://api.getmatter.com/public/v1/items?status=queue&order=library_position" \
  -H "Authorization: Bearer $MATTER_TOKEN"

# All library items (queue + archive) in manual order
curl "https://api.getmatter.com/public/v1/items?order=library_position" \
  -H "Authorization: Bearer $MATTER_TOKEN"

# Inbox in feed order
curl "https://api.getmatter.com/public/v1/items?order=inbox_position" \
  -H "Authorization: Bearer $MATTER_TOKEN"
order valueDescription
updatedSort by last-updated timestamp (default). Works with all status filters and updated_since.
library_positionSort by library position (manual queue ordering). Items without a library entry sort last.
inbox_positionSort by inbox feed position (newest first). Items not in the inbox sort last.
No status filter is required for position orderings — items without a position sort last.

Position fields and incremental sync

Every item includes library_position and inbox_position fields, regardless of the order parameter used. This means you can use order=updated with updated_since for efficient incremental sync, and still use the position fields to sort items locally into app order:
# Incremental sync — fetches only changed items
params = {"updated_since": last_sync, "limit": 100}
changed = fetch_all_pages(params)

# Update local cache with changed items
for item in changed:
    local_db[item["id"]] = item

# Display in app order using position fields
queue_items = sorted(
    [i for i in local_db.values() if i["status"] == "queue"],
    key=lambda i: i["library_position"] or 0,
    reverse=True,
)
Annotations, tags, and other list endpoints always use updated_at ordering.