Guide

Poll the OneLifeVibe event log with a cursor in Python

Read the OneLifeVibe event log with GET /api/platform/v1/events, page through results with the cursor field, and resume from the last sequence number.

Updated November 6, 2026

Stack
Python (requests)
API
Platform API v1 · Connectors

The code

import time
import requests

BASE = "https://onelifevibe.com/api/platform/v1"


def poll_events(key: str, after=None):
    events = []
    while True:
        params = {"limit": 100}
        if after is not None:
            params["after"] = after
        res = requests.get(f"{BASE}/events", params=params, headers={"Authorization": f"Bearer {key}"}, timeout=30)
        if res.status_code == 429:
            time.sleep(int(res.headers.get("Retry-After", "60")))
            continue
        res.raise_for_status()
        page = res.json()
        events.extend(page["events"])
        after = page["cursor"]
        if not page["has_more"]:
            return events, after

The facts it relies on

Related guides

What you are building

You are building a small Python poller that reads the OneLifeVibe event log through GET /api/platform/v1/events and keeps its place with a cursor. The endpoint answers with events, a cursor number and has_more. You hand the cursor back as the after query parameter to get the next page, so each run picks up where the last one stopped instead of rereading the whole log.

after is a sequence cursor. Leave it out and you start at the beginning of the log. limit takes 1 to 100 and defaults to 25. You can narrow the response with world and type.

Polling works on every plan, including the free Sandbox, and returns the same records as webhooks. That makes this a reasonable starting point even if you plan to move to webhooks later.

Before you start

You need a Platform API key that carries the events:read scope. The code sends it as an Authorization: Bearer header, so keep the key out of source control and read it from an environment variable.

Install requests if you have not already, and point BASE at https://onelifevibe.com/api/platform/v1. Nothing else is required; the poller is one function plus a loop.

On the free Sandbox plan the limits are 1,000 calls a day and 10 requests a minute. A page size of 100 keeps you under that for most logs, because a single call returns up to 100 events.

How the code works

The function takes your key and an optional after value, then loops. Each pass builds a params dictionary with limit set to 100 and adds after only when it has a value, so the first call starts at the beginning of the log. The GET request goes to BASE/events with the Bearer header and a 30 second timeout.

If the API answers 429, the code reads the Retry-After header, sleeps that many seconds (60 when the header is missing) and continues. That continue repeats the same page rather than moving on, so no page is skipped. Any other non-2xx status goes to raise_for_status and stops the run with an exception you can catch.

When a page succeeds, the function appends page["events"] to the running list, sets after to page["cursor"] and checks page["has_more"]. If it is true, the loop requests the next page. If it is false, the function returns the events and the cursor, which is the value you save for the next run.

Testing it

Call poll_events with no after value first so you start at the beginning of the log, then print the length of the returned list and the cursor. Every page should contain events, cursor and has_more. Lower the limit while you test if you want shorter pages.

To exercise the rate limit path, send requests faster than 10 a minute on the Sandbox plan. The response is 429 rate_limited with a Retry-After header, and the function should sleep and retry instead of raising.

Once a run finishes, pass the returned cursor back in as after and confirm the next call returns only newer events. If you add a world or type filter, check that the cursor still advances the same way.

Going to production

Store the cursor outside the process. Write it to your database or a file only after you have processed the events from that page, then read it back at the start of the next run. If a run crashes between reading events and saving the cursor, you will reprocess at most one page, so make your handler idempotent.

Keep limit at 100 for normal catching up, keep the timeout, and keep the 429 branch. The limit is per minute, so the Retry-After sleep is usually short; log it so you notice when it starts happening often.

If you later add webhooks, remember they deliver the same records as polling. You can run both while you migrate, using the cursor to backfill anything you missed.

Questions

What scope does the events endpoint need?

GET /api/platform/v1/events requires the events:read scope. Send your Platform API key in the Authorization header as a Bearer token.

How do I get the next page of events?

Pass the cursor from the previous response back as the after query parameter. has_more tells you whether another page exists, and limit accepts 1 to 100 with a default of 25.

What does a 429 response look like?

When you go over the per-minute limit the API returns 429 with the error code rate_limited and a Retry-After header. Wait that many seconds and retry the same request.

Try it against the real API. A free Sandbox key reads the catalogue and the event log at once, no card.

Get a free key Read the docs

Written from the OneLifeVibe tool registry and platform configuration, and checked automatically before publishing. Something wrong? Tell us.