Read API overview¶
The full per-endpoint reference is on Endpoints. This page covers the cross-cutting concerns: authentication, versioning, pagination, correlation IDs, errors. Read this once and the per-endpoint pages become a quick lookup.
Base URL¶
| Environment | Base |
|---|---|
| All usage | https://api.revento.app/api/v1 |
Use this base URL for all API requests. To test your integration, connect it to an event you control through the standard OAuth flow; the base URL stays the same.
URLs in Endpoints are written relative to the base.
Authentication¶
Every API request requires a Bearer header with an installation token (event-scoped) or user token (participant-scoped). Token type matters per endpoint - see the table on each endpoint page.
Wrong token type for an endpoint returns 403 user_token_required or 403 installation_token_required. See Errors.
API versioning¶
Pin a version with the Accept header. Today there's only v1:
If you omit the Accept header, you get the current default version. Fine for development, risky for production - pin the header so a version transition can't silently change your response shape.
Versioning commitment: any previous version is supported for at least 6 months after the next version is announced, with the deprecation surfaced in the changelog and in Revento's integration-management notices.
Correlation IDs¶
Send a UUID on every request:
We echo it back in the response and write it to our logs. When you contact support, hand them this UUID - investigation drops from minutes to seconds.
You can use any UUID format (v4 is fine). It only needs to be unique per request on your side.
Pagination¶
List endpoints return:
To fetch the next page, pass next_cursor as the cursor query parameter:
GET /events/{event_id}/participants?limit=25
GET /events/{event_id}/participants?limit=25&cursor=eyJjIjogIjI...
Rules:
- The cursor is opaque. Don't parse it. Format may change without notice.
has_moreis the canonical "more pages exist" signal. Don't rely onnext_cursor != null- cursors are opaque, and a non-null final cursor is permitted by the contract.limitdefaults to 25, max 50. Kept conservative because list responses can carrycustom_form_fieldsper row and may approach the per-response payload cap on rich-form events. If you receive413 payload_too_large, reducelimitand retry.
Errors¶
Every error response has the same envelope:
{
"error": "string_code",
"message": "Human-readable explanation",
"request_id": "UUID matching X-Revento-Request-Id"
}
The error code is the machine-readable identifier. Branch on this in your code. The message is for humans (logs, dashboards, operator notes); it may evolve.
Full error catalog is in Errors. The codes you'll see most often:
| Code | Meaning |
|---|---|
token_expired |
Refresh and retry |
token_revoked |
Permanent - re-consent required |
insufficient_scope |
Token doesn't grant this endpoint |
event_not_authorized |
Token is for a different event |
rate_limit_exceeded |
Back off (Retry-After header has duration) |
Idempotency¶
All current endpoints are read-only GETs, so no idempotency keys are required. Repeating a request gives the same response (modulo data changes between calls).
Headers we always send¶
Every API response includes:
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 1747000000
X-Revento-Request-Id: {your UUID echoed}
Content-Type: application/vnd.revento.v1+json; charset=utf-8
See Rate limits for header semantics.
Time format¶
All timestamps in request and response bodies are ISO 8601 in UTC:
We never return local times. Convert to local at your display layer using whatever your stack provides (Intl in browsers, pytz / zoneinfo in Python, etc.). Same convention applies to webhook payloads.
Cursor stability¶
If you're storing cursors (e.g. for resumable sync), be aware:
- Cursors remain valid for at least 24 hours.
- Cursors are tied to the (endpoint, query, token) tuple - a cursor from
/events/{a}/participantsdoesn't work on/events/{b}/participants. - Within a single page response, the result set is point-in-time consistent.
- Across pages fetched at different times, rows may appear, disappear, or shift because the underlying data changed. A newly-created row may appear on a later page even if it would have sorted onto an earlier one; a deleted row may simply be absent.
- Cursors remain safe to reuse even when the underlying data changes. They advance the walk; they do not promise a mutation-free snapshot across the entire pagination session.
- After 24 hours we make no guarantee. If you need long-running paginated reads, complete them within a session.
If you need strict change tracking while paginating, treat webhooks as the source of truth for mutations and use pagination for baseline syncs, not for change notification.
Integration management¶
Revento provides integration-management tools for reviewing metadata, rotating secrets, testing webhooks, and inspecting delivery history.