Skip to content

Concepts in depth

The mental model covers the 5-minute version. This page is the longer companion, organized so you can jump directly to whichever concept you need.

Per-event binding

The most important shape of the framework: every authorization is scoped to exactly one event. Not to a user account. Not to an organization. Not to all events an organization has ever run.

When an organizer connects your integration, they pick one specific event and run through the consent screen for that event. The resulting installation token is bound to a (event_id, organization_id, integration_id) tuple. Calling the API for any other event with that token returns 403 event_not_authorized.

If an organization runs ten events and wants your integration on all ten, the organizer connects it ten times — ten consent screens, ten tokens, ten independent connections. There is no org-level shortcut.

The implication for your product: your customer-facing UX should be event-scoped, not org-scoped. Don't show "your Spring Convention 2026 sync is configured" alongside "click here to also sync your Summer Convention 2026" as a one-tap upgrade — make them connect each event explicitly.

Two token types

Installation token User token
Issued by Organizer connect flow Login with Revento
Bound to (event, organization, integration) (user, event, integration)
Acts as "The integration, on behalf of this event" "This specific participant, in this event context"
Holder Your backend Your backend (per signed-in user)
Calls Event-scoped endpoints (/events/{id}/...) User-scoped endpoints (/me/...)
Lifetime 1h access + 90d sliding refresh, 1y hard cap Same
Revocation initiators Organizer / Revento / your unpublish User / Organizer / Revento / your unpublish

Mixing token types is a 403 with a structured error code:

  • Use installation token on /me/...403 user_token_required
  • Use user token on /events/{id}/...403 installation_token_required

A typical integration holds:

  • One installation token per event it's connected to (5 events = 5 installation tokens, all sharing the same client_id).
  • Zero or many user tokens per event — one per (user, event) tuple where a participant has signed in.

These are stored separately. See organizer-connect → storage and login-with-revento → multi-event participants for schema sketches.

Read-only

The framework has no write endpoints. You cannot:

  • Create events
  • Modify event metadata
  • Approve / reject / cancel applications on behalf of an organizer
  • Create or modify participants
  • Send notifications via Revento on behalf of organizers
  • Publish program changes

If your design depends on writing back to Revento, redesign around that constraint or write to your own storage. Most integrations either don't need writes (sync-out, analytics, badge printing) or arrange writes through the organizer's own UI (organizer manually approves applications in Revento; your integration reacts to the resulting webhook).

Formal organizations only

A "formal organization" in Revento is a verified legal entity (registered tax identifier such as NIP). Formal status is the gate for several things:

  • Authorizing any integration: only formal orgs can connect integrations. Informal orgs don't even see an integrations panel.
  • Creating in-house integration definitions: only formal orgs.
  • Adding auth-required webview pages: requires an integration, which requires formal status.

If an organizer can't connect your integration, the answer is to complete organization verification first.

Scope evolution

When you ship a new version of your integration that declares a scope existing connections don't have, every existing connection enters a "re-consent required" state:

  1. The previous token continues to work for the previous scope set.
  2. The new scope is unavailable until each organizer re-consents through the OAuth flow.
  3. Organizers see a banner in their integrations panel asking them to grant the new permissions.
  4. There is no silent / "banner-only" path that adds scopes without explicit consent.

Same rule for renaming or splitting existing scopes. Treated identically to net-new scopes — re-consent required, no silent migration.

The implication: think hard about your scope set up-front. Adding scopes later is possible but every existing customer has to re-click. For minor versions where the data access doesn't change, no re-consent is needed.

See Scopes for the full versioning rules.

Lifecycle cascades

Several events invalidate tokens. Internalize them now — your integration must handle each gracefully.

flowchart LR
    A[Organizer revokes] --> X((Tokens invalidated))
    C[Org loses formal status] --> X
    D[You unpublish integration] --> X
    E[Revento suspends integration] --> X
    F[Participant revokes Login with Revento] --> Y((User tokens<br/>for that user invalidated))
    X --> W[data.deletion_required webhook]
    X --> Z[Subsequent API calls<br/>return 401 token_revoked]

The first five cascade across all tokens in scope of the cascade. The sixth (participant-side revocation) is narrower — it invalidates only that participant's user tokens for your integration in that event context.

Build with this in mind:

  • Catch 401 token_revoked on every API call. It's not transient.
  • Catch 400 invalid_grant on refresh attempts. It's the refresh-token equivalent of 401 token_revoked — permanent revocation.
  • Subscribe to data.deletion_required and act on it. The 30-day deletion deadline is contractual; we audit dispatch but cannot inspect your storage.
  • Subscribe to user.revoked_access if you hold per-user state.
  • Don't rebuild a connection automatically when you see an invalidation. The organizer (or participant) revoked deliberately — surface the disconnect to your operators or to the user, but don't try to reconnect without an explicit action.

See webhook event catalog for full payload schemas of data.deletion_required, user.revoked_access, event.unpublished, integration.suspended, integration.unpublished.

What doesn't change

If you're already familiar with OAuth 2.0:

  • Authorization Code with PKCE — standard.
  • Refresh-token rotation with one-time use — standard, plus family-revoke-on-reuse. See refresh tokens.
  • Bearer header for API calls — standard.
  • Versioned API via Accept header — standard.
  • HMAC-SHA256 signed webhooks with timestamp + body.

Where we diverge from the most generic OAuth integration:

  • Per-event binding with an event_id parameter on the authorization request (organizer flow) — most OAuth providers don't have this.
  • No event_id parameter on the participant flow, because we resolve it from the participant's eligible-events set — most OAuth providers can't do this because they don't know your event context.
  • Read-only — most OAuth providers offer write APIs. We don't.
  • Formal-organization gate — only verified legal entities can authorize integrations.