GET /v1/events returns the events your API key creator has created. The key chooses the scope: results always belong to the key’s owner, and a key can never read another creator’s events.
Credentials: secret keys via P-Sec-Key, publishable keys via P-Pub-Key or ?pPubKey=. Scope required: events.read (granted by the events product).
Deleted events are excluded. Results are ordered by creation time, newest first unless sort=OLDEST is requested.
GET /v1/events
Returns a page of events plus a page-based pagination object. Unlike highlight reads, which use opaque cursors, Events uses page / limit.
pageintegerQueryOptional0Zero-indexed page number. Negative values fail validation with 400.
limitinteger 1–100QueryOptional20Items per page. Out-of-range values fail validation with 400 — never clamped. The effective value echoes back in pagination.limit.
statusenumQueryOptional—One of DRAFT, PUBLISHING, PUBLISHED, LIVE, ENDED, ARCHIVED, or TRASH. Any other value fails validation with 400.
publishing_statestringQueryOptional—Exact pipeline state, such as PUBLISHED, DONE_FINALIZE_EVENT, or RUNNING_FINALIZE_EVENT. Case-insensitive; matched exactly.
tagstringQueryOptional—Exact event tag. Use search for partial matches.
searchstringQueryOptional—Case-insensitive match across the event title, description, tag, and category. Wildcard characters are treated as spaces.
fromISO dateQueryOptional—Only events whose starts_at is on or after this timestamp.
toISO dateQueryOptional—Only events whose starts_at is on or before this timestamp.
sortenumQueryOptionalLATESTLATEST or OLDEST, applied to event creation time (created_at).
——Path / BodyOptional—None. Authentication travels in P-Sec-Key, P-Pub-Key, or ?pPubKey=.
curl "https://api.pulluptoplay.com/v1/events?limit=10&status=PUBLISHED&sort=LATEST"
const params = new URLSearchParams({
limit: "10",
status: "PUBLISHED",
sort: "LATEST",
});
const response = await fetch(`https://api.pulluptoplay.com/v1/events?${params}`, {
headers: { "P-Sec-Key": process.env.PULLUP_SECRET_KEY! },
});
if (!response.ok) {
const failure = await response.json
import os
import requests
def list_events(limit: int = 10, status: str | None = None) -> dict:
params = {"limit": limit, "sort": "LATEST"}
if status:
params["status"] = status
response = requests.get(
"https://api.pulluptoplay.com/v1/events",
params=params,
{
"status": "success",
"code": 200,
"message": "Events retrieved",
"data": {
"events": [
{
"id": "phETPR44vAcaZVHs",
"creator_id": "d1ddf34f-65a0-4203-b025-1533ef0b3812",
"title": "The Future Stack Summit 2026",
"description": "A full day of panels, workshops, and deep dives.",
"tag": "the-future-stack-summit-2026",
"unique_link": "the-future-stack-summit-2026-42s33O"
Every nullable above arrives explicitly as null — published_at, ends_at, publishing_error, and topic are never omitted. Object fields (location, timeline, settings, permissions, asset, category) are always objects, empty when unset.
Page numbers are stable only for a fixed dataset. If events are created or deleted between calls, use limit=100 and re-read from page=0 when the set changes materially. Continue while pagination.has_more is true:
pageintegerResponseRequired—The page that produced this result, echoed from the request (or 0 when omitted).
limitintegerResponseRequired—The effective page size, after validation.
totalintegerResponseRequired—Total non-deleted events matching the filters for this key. 0 when nothing matches.
total_pagesintegerResponseRequired—ceil(total / limit), or 0 when total is 0. Use it to render a page picker.
has_morebooleanResponseRequired—true when another page exists. Decides continuation for drain loops.
const all: unknown[] = [];
let page = 0;
let hasMore = true;
while (hasMore) {
const params = new URLSearchParams({ page: String(page), limit:
import os
import requests
def drain_events(limit: int = 100) -> list:
events = []
page = 0
while True:
response = requests.get(
"https://api.pulluptoplay.com/v1/events",
params={"page": page, "limit": limit},
headers={"P-Sec-Key": os.environ["PULLUP_SECRET_KEY"]},
timeout
idstringResponseRequired—Event id. Text, not a UUID — never assume a format beyond non-empty.
creator_idstring (uuid)ResponseRequired—Owner of the event. Always the API key’s creator.
title / description / tagstringResponseRequired—Display copy. Empty strings when unset; never null.
unique_linkstringResponseRequired—Public event slug used in Pullup URLs.
statusstringResponseRequired—Event lifecycle status. Filterable with ?status=.
publishing_statestringResponseRequired—Pipeline state at read time. DONE_FINALIZE_EVENT is the common healthy terminal value.
published_at / starts_at / ends_attimestamp | nullResponseOptional—Event dates. ends_at is null for open-ended events; published_at is null before first publish.
location / timeline / settings / permissions / asset / categoryobjectResponseRequired—Event configuration objects owned by the creator. Empty objects when unset — never omitted.
is_deletedbooleanResponseRequired—Always false in list responses; deleted events are filtered out before pagination.
created_at / updated_attimestampResponseRequired—Creation and last-update timestamps. created_at drives sort and pagination order.
401 Authentication required401AuthRequired—No key was extracted. Send exactly one credential.
401 Invalid API key401AuthRequired—Unknown, revoked, malformed, or cross-environment key.
API key is missing events.read scope403AuthRequired—The key lacks the events product. Widen products or issue a key with events under Credentials.
Validation failed400QueryRequired—Invalid status, out-of-range limit, negative page, malformed from / to, or an unknown sort. Per-parameter details arrive in data.
Missing scope returns:
{
"status": "client_error",
"code": 403,
"message": "API key is missing events.read scope"
}Invalid filters return:
{
"status": "client_error",
"code": 400,
"message": "Validation failed",
"data": {
events product.