Arranger manual

Last updated: 2026-04-25

A pedagogic walk-through of the platform: create an adventure, fill it with puzzles, schedule an event, add teams, and watch them play. Read it once start to finish, or jump to a section from the table of contents.

Welcome

Zonventure is a platform for running location-based adventure games β€” treasure hunts, team-building events, school field trips. As an arranger you author the puzzles, set up an event, and the players walk around with their phones answering them.

Four words to know

  • Adventure β€” a reusable script. Pages of puzzles in order. Like a book.
  • Assignment β€” a paid licence to run an adventure once for up to N teams. You buy these from the Store.
  • Event β€” one specific playthrough at a specific time. Created from an assignment.
  • Team β€” a group of players in an event, identified by a team name. Each player gets their own magic-link to log in as part of the team.
Mental model: an Adventure is a recipe; an Assignment is the right to cook it once; a Event is one specific dinner; a Team is the people sitting at a table.

First steps

When you sign up, you create an organization. Everyone in your organization shares the same adventures, assignments, and events.

Verify your email

After signup we email a verification link. You can log in before clicking it, but money-touching actions (buying assignments, scheduling events) are blocked until you verify. The dashboard shows a banner with a "Resend" button if it didn't arrive.

[Screenshot: dashboard with the unverified-email banner]

The dashboard

The dashboard is your home: at-a-glance view of upcoming events, ready-to-schedule assignments, and shortcuts to the things you most often do.

[Screenshot: a populated arranger dashboard]

Authoring an adventure

Adventures live in the Library. You can author your own, or pick one from the global catalog (the catalog is curated by the platform admin and always free to use).

Create an adventure

  1. Click "Library" in the sidebar.
  2. Press "New adventure".
  3. Give it a title. The slug is auto-derived but editable; once players have started an event with this slug, don't change it.
  4. Save. You're taken to the puzzle editor.
[Screenshot: Library tab with the New adventure button highlighted]

Adventure metadata

Beyond title and slug, an adventure can carry:

  • Intro and outro text β€” markdown shown to players before the first puzzle and after they finish. Set the tone here ("Welcome to the King's Hunt!") and wrap up with congratulations.
  • Colors β€” two accent colours that override the default pink branding for players in this adventure. Useful for white-labelled events.
  • Avatar β€” an image rendered as the adventure's logo on the dashboard, the live view, and the player welcome screen.

Adding puzzles

A puzzle is one page of the adventure. Players see them in order; only after solving the current page do they advance to the next one.

[Screenshot: the puzzle editor showing a puzzle in edit mode]

Title and prompt

The title appears as a heading on the player's screen. The prompt is the body β€” render it with markdown for formatting, links, lists.

Tip: keep prompts short. Players read them on a phone, often outdoors.

Answer types

  • Text answer β€” list one or more accepted answers. The player's typed answer is matched case-insensitively, with whitespace trimmed. Use multiple entries to allow synonyms ("blue", "blΓ₯", "blueberry").
  • No answer β€” leave the accept list empty. The player sees a "Continue" button instead of an input field. Useful for narrative pages or location-only puzzles.

Hints

Each puzzle can carry an ordered list of hints, each with a delay (in seconds) before it becomes revealable. The "Reveal hint" button on the player's screen unveils them one at a time.

Delays are measured from when the team arrives at the puzzle, so a stuck team naturally gets help, while a fast team never sees the hints.

Images

Attach up to a few images per puzzle. They render under the prompt. Photos of the location, illustrations, or visual clues. Each image is capped at 5 MB.

Location gates

Optionally pin the puzzle to a GPS location with a radius. Players can read the prompt anywhere, but they can't submit the answer until they're inside the radius. The map widget in the editor lets you click to place the pin.

[Screenshot: the location-gate map widget]
GPS accuracy varies. A 50-metre radius is usually a sensible minimum β€” under that, urban canyons and indoor walls cause false negatives.

Reordering and disabling

Drag puzzles to reorder. Disable a puzzle to hide it from players without deleting it β€” useful for swapping seasonal content.

Preview

The "Preview" button on the adventure detail page renders a sandbox playthrough. No team progress is recorded β€” it's your test rig.

How the event flow fits together

Before scheduling your first event, take a moment to understand the chain:

Adventure  β†’  Assignment  β†’  Event  β†’  Teams  β†’  Players
  • You author or pick an Adventure (free).
  • You buy an Assignment for that adventure: pays for up to N teams.
  • You create a Event from the Assignment: ties it to a specific date/time.
  • You add Teams to the Event: each team is a group of players.
  • You share each Player a magic link: they tap, the event starts, they play.
One assignment = one event. If you want to run the same adventure twice, buy two assignments.

Buying team-slot assignments

  1. Click "Store" in the sidebar.
  2. Pick the adventure you want to run.
  3. Choose how many teams will play (1–100).
  4. Click "Buy". You're sent to Stripe Checkout.
  5. After payment, you're sent back to the dashboard with a "Schedule now" prompt on the new assignment.
[Screenshot: the Store with adventure cards]
Refunds: if you bought the wrong assignment, contact support. Refunds are admin-only β€” they touch real money.

Creating an event

  1. Click "Events" in the sidebar, then "Schedule event".
  2. Pick the assignment you want to use (only unused assignments are listed).
  3. Give the event a name (eg. "Office team-build, Friday afternoon"). This is for your benefit; players don't see it.
  4. Pick a date and time. You can also leave it blank and start the event manually later.
  5. Confirm the no-minors attestation, or pick the COPPA path if you're running for under-13s.
  6. Save. The event appears in the Events list with state "scheduled".
[Screenshot: the schedule-event dialog]
A scheduled run auto-starts the moment its time arrives, even if you've forgotten to click Start. Players who open their magic link at the scheduled minute get going immediately.

Adding teams and sharing magic links

Adding a team

  1. Open the event's detail page from the Events list.
  2. Click "Add team".
  3. Type the team name and the player names (one per line, or paste from a CSV).
  4. Save. Each player slot is created with a fresh magic-link token.
[Screenshot: the add-team dialog]

Sharing magic links

Each player's magic link is what they tap to join the event. The event-detail page has a "Team links" panel: copy individual links, copy a CSV of all team members, or copy a single "captain link" per team that the captain forwards to teammates.

[Screenshot: the team links panel with copy buttons]
Magic links are sensitive β€” anyone with the URL can play as that slot. Don't paste them into public Slack channels. The dashboard's "Rotate token" action mints a new link if one leaks.

Token expiry

Slot tokens expire seven days after the event's scheduled time by default. The team-links panel shows "expires in Nd" so you can spot links that need re-sharing.

Running the event

Start, pause, resume

A scheduled run auto-starts at its time, but you can also start it manually from the event-detail page. Pause the event to freeze player progress (lunch break, weather delay), then Resume to continue.

The activity feed

The event-detail page has a live activity feed β€” answer attempts (right and wrong), team completions, gate reaches, state changes. Useful for noticing a stuck team in real time.

[Screenshot: activity feed during a live event]

The live view

Each event has a public-ish "live view" URL β€” a leaderboard plus optional audience map. Open it on a TV in the lobby; spectators can see team progress without logging in.

The map is OFF by default for privacy. Toggle it on from the event settings if your players are okay with their position being shown to the audience.

[Screenshot: the live view leaderboard with map enabled]

Completion

When every team finishes, the event automatically transitions to "completed". Players see the outro text and a stats screen (right answers, distance walked, total time). The event row in your dashboard moves to the "completed" section.

Webhooks: outbound integrations

Webhooks let you hook the platform up to your own systems β€” push events into Slack, trigger a Zapier flow, update a corporate dashboard, send parents a "your kid's team finished" SMS. The platform POSTs JSON to an HTTPS URL you control whenever something interesting happens.

When to use webhooks

  • Show a live leaderboard on a TV in your lobby, branded your way.
  • Notify parents (school events) when their child's team finishes.
  • Trigger fulfillment in your own ops system when an event completes.
  • Pipe events into your analytics warehouse.

The event catalog

Seven event kinds in v1:

  • event.scheduled β€” a new run was created.
  • event.started β€” an event actually started (manual or auto-promote).
  • event.completed β€” all teams finished.
  • team.created β€” a new team was added to an event.
  • team.completed β€” a team finished. Includes their name and run id.
  • purchase.paid β€” an assignment was purchased.
  • purchase.refunded β€” a purchase was refunded.

Configure an endpoint

  1. Click "Webhooks" in the sidebar.
  2. Click "Add endpoint".
  3. Give it a name, paste your URL, tick the events you want.
  4. Save. A secret is shown once β€” copy it now.
[Screenshot: the webhook create dialog with the secret reveal]

Verifying signatures

Every POST carries an X-Zv-Signature header of the form sha256=<hex> β€” that's HMAC-SHA256 of the raw request body, keyed by your secret.

Verify in your handler before trusting the body:

# Pseudocode
sig    = request.header('X-Zv-Signature')   # "sha256=abcd..."
body   = request.raw_body                   # bytes, not parsed JSON
secret = STORED_SECRET
expected = "sha256=" + hmac_sha256(secret, body).hex()
if not constant_time_equal(sig, expected): reject 401
process(parse_json(body))
Always compare with a constant-time comparator (hmac.Equal in Go, timingSafeEqual in Node, hmac.compare_digest in Python). A naive == leaks bytes via timing.

Send a test

Use the "Send test" button on each endpoint to fire a synthetic webhook.test delivery. The customer-side handler can verify the signature without waiting for a real lifecycle event.

[Screenshot: the Send test button + a delivered toast]

Delivery and retry

A delivery worker drains every 5 seconds. On any non-2xx response or timeout we retry with exponential backoff (1m β†’ 5m β†’ 30m β†’ 2h β†’ 8h β†’ 24h, six attempts). After that the delivery is "dead-lettered" β€” no further retries.

Reply with a 2xx as quickly as you've persisted the event; do the actual work async. The faster you reply, the fewer duplicates we have to enqueue.

Dedupe

Use the X-Zv-Delivery-Id header (a 32-char hex) as your idempotency key. Duplicate deliveries during retries reuse the same id; insert it into a seen_delivery_ids table with ON CONFLICT DO NOTHING and skip if it was already there.

Rotating the secret

If a secret leaks, click "Rotate secret" on the endpoint. A new secret is minted; the old one stops working immediately. Deploy the new value to your verifier first to avoid a brief gap of failed deliveries.

Account, data and deletion

The Settings page has the operational controls for your own account.

  • Change password β€” Requires the current password. Other sessions are signed out on success.
  • Change email β€” We send a confirmation link to the new address. The change only takes effect when you click it.
  • Download my data β€” A single JSON file with your account info plus your organization's runs, teams, adventures, assignments and purchases. The GDPR-friendly export.
  • Delete account β€” If you're the last member, your organization is deleted with you. All runs, teams, adventures, assignments. Cannot be undone.

Getting help

If something doesn't work as described here, or you're unsure how to do something, start with the event's activity feed (any errors are logged there for the team that hit them).

For platform-level support, contact the operator listed at the bottom of the Privacy page.

This manual evolves. If you read something that's wrong or unclear, tell support β€” clearer docs help every other arranger after you.