Getting started

From nothing to a
working integration.

Every integration starts the same way: you email us, and we create your organization. There is no self-serve signup and nothing you can try first — nothing works until you have an organization ID, and only we can issue one. What changes after that is how much you need: registration and checkout is three steps and no API key, while the server-to-server products also need a key, a webhook and a promotion step.

First

What your integration needs

Find your row, then read only the track that applies to it. Most partners are in the top half of this table and never need a key at all.

What you're building What you need from us Which track
The checkout drawer An event ID, with checkout enabled on that event. Your organization ID for branding. Registration & checkout
Event listings from the public API An organization ID — a UUID. Nothing else. Registration & checkout
Event-card fragments An organization ID. Registration & checkout
Hosted storefront & booking An organization ID, and your branding set on your org record. Registration & checkout
The org parent portal An organization ID. It's one link. Registration & checkout
Clearance inside registration Nothing to integrate — but tell us your requirement set so we configure what gets collected. Registration & checkout
Candidate clearance API An organization ID and a Partner API key. Partner API
Staffing & jobs API A Partner API key (the same key covers clearance) and a webhook endpoint. Partner API

The common case needs no API key

Registration and checkout — what most partners come for — is entirely key-free. The public event endpoints are unauthenticated because they only ever return published, public event data, and the checkout drawer authenticates the parent, not you. So the whole integration is one UUID and no secret management.

Keys exist for the server-to-server products, clearance and staffing, where you're acting on your own behalf rather than rendering a parent's purchase.

Email us this

This is step one for everybody, so it's at the top rather than buried at the bottom. Paste it, fill in what applies, and we can usually create everything in one pass instead of three rounds of email. Send it to support@thegoodgame.com.

Everyone fills this in
Organization name:        e.g. Riverside Sports
Primary contact + email:  who we send the organization ID to

Products we want:         registration & checkout / clearance / staffing
Way for each:             hosted / embedded-SDK / API
Checkout mode:            single-camp (default) / multi-camp (enable Multi-Camp Cart)
Domains we'll embed on:   e.g. www.riversidesports.com, camps.riversidesports.com

Branding:                 logo file, display name, the word you use for events
                          ("camps", "clinics", "sessions"), Meta Pixel ID if any

Clearance requirements:   which waivers, forms and documents each event must collect,
                          and how strictly each policy must be accepted
                          (informational / checkbox / drawn signature)
Only if you need the Partner API
Webhook URL:              https://… (must answer 2xx within 15 seconds)
Scopes needed:            e.g. jobs:write, coaches:read, offers:write
Staging as well?          say yes — and ask for a staging organization AND a staging
                          event, or your first request 404s for boring reasons

Not sure which products or which way? Ways to integrate explains the three shapes, and Example integrations shows four businesses picking different mixes — find the one that looks like yours and copy it.


Registration & checkout

Three steps, no key

The whole track, for selling registrations on your own site or ours. If this is all you're doing, you're finished after your first booking — everything past the next rule is about the Partner API and does not apply to you.

  1. Email us and get your organization ID

    Send the block above. You get back a UUID, and we set your branding on your org record at the same time.

    The organization ID is not a secret and grants nothing on its own — it's a view filter. It's safe in client-side code, in a URL, and in your public HTML.

  2. Ask us to enable checkout on the events you're selling

    An event needs a checkout configuration before it can take a registration. Without one the drawer opens and says registration isn't open — the single most common "why doesn't this work", and not a code problem.

    Choose your checkout mode: single-camp checkout is the default (Multi-Camp Cart OFF). For several camps from your organization in one cart, one checkout and one charge, ask your TGG contact to turn Multi-Camp Cart ON for your organization in TGG admin. This is separate from enabling checkout on each event: it is not a per-event setting or a code flag. Preview both options.

  3. Drop in the loader and mark your buttons

    Two lines, and that's the entire embedded integration. See the checkout drawer for the JavaScript API, or hosted storefront if you'd rather just link to us and write no code at all.

    HTML
    <script src="https://my-v2.thegoodgame.com/embed.js" defer></script>
    <button data-tgg-checkout data-event-id="{event_id}">Register Now</button>

    The example above opens checkout directly for one camp. When Multi-Camp Cart is enabled, the existing loader also shows the cart widget without a partner deploy. Use the Add to cart buttons and cart API for your custom camp cards, and preview cart styling for colors, placement and labels. Widget styling does not turn the checkout mode on or off.

Test on staging first by swapping the loader to staging.my-v2.thegoodgame.com/embed.js with a staging event ID — see Environments — then walk the go-live checklist before your first real registration.

Your first calls

Once you have an organization ID, this is your entire read surface for building a catalogue. No key, no headers, no signing — these endpoints are unauthenticated because they only return published, public event data.

cURL — no auth
# 1. Your organization's events, for a listing page.
curl "{API_BASE_URL}/api/v1/organizations/{organization_id}/events?size=5"

# 2. One event in full — schedule, venue, pricing, requirements, FAQs.
curl "{API_BASE_URL}/api/v1/events/{event_id}"

# 3. Live pricing and availability — the same bootstrap our own checkout reads,
#    so your page can't advertise a session the drawer will refuse.
curl "{API_BASE_URL}/api/v1/ec/events/{event_id}/checkout-config"

Every field, plus two response-shape gotchas worth knowing before you write your parser, is in the API section.


Partner API

Four more steps

Only for clearance and staffing. These come in addition to getting your organization — you still start with the same email.

  1. We issue your API key

    You can't mint your own. It's shown to you exactly once at creation and stored only as a SHA-256 hash, so if you lose it we can't recover it — only replace it. Details in API keys in detail.

  2. Build against staging

    Staging is a separate database: your production organization ID, event IDs and keys do not exist there. Ask for a staging organization and at least one staging event when you ask for the key.

  3. Register your webhook URL

    Send us an HTTPS endpoint; we generate your signing secret and can fire a test delivery at it, so you can prove your verifier works before a real event depends on it. See Registering a webhook — the test payload has a shape that catches people out.

  4. We verify your sandbox and promote you to live

    We confirm four things, then mark you live. Sandbox & promotion covers what that does and, more importantly, what it doesn't.

API keys in detail

Worth reading before you write your secret-management code — two of these will surprise you.

Sending your key — either header works
curl "{API_BASE_URL}/api/v1/partner/jobs" \
  -H "Authorization: Bearer tgg_pk_live_xxxxxxxxxxxxxxxxxxxxxxxx"

# or, if a bearer header is awkward in your stack:
curl "{API_BASE_URL}/api/v1/partner/jobs" \
  -H "X-API-Key: tgg_pk_live_xxxxxxxxxxxxxxxxxxxxxxxx"
Property How it works
Format tgg_pk_live_ followed by 24 random base64url characters. Malformed keys are rejected before any lookup, so a truncated key gives you 401 Missing or malformed API key rather than something confusing.
Shown once Displayed at creation and never again — we store only its SHA-256 hash, so we cannot recover or re-read it. Keys are told apart by the label you give us when we create one, so name them for where they run ("prod-api", "staging-ci") rather than expecting us to identify them later.
Scopes Recorded on the key. On staffing and clearance they are not enforced yet — a valid key reaches every partner route regardless of what it was granted. Ask for the narrow set anyway, and treat the key as fully privileged in your threat model until enforcement ships.
Expiry Optional. If set, the key stops working at that moment with 401.
Rotation Multiple live keys per partner are fine, so rotate without downtime: ask for the new key, cut over, then have us revoke the old one. Revocation is immediate.
Rate limit Your record carries 60 requests/minute. It isn't enforced today, but it's the budget we'll hold you to — don't design for burst capacity you'd lose.
Org suspension Access is per partner organization, not per key. If your org is suspended, every key returns 401 immediately — so a sudden total 401 across all keys is an account question, not a code bug.

Every key says live, including your staging key

The _live_ in tgg_pk_live_… is part of the fixed prefix, not an environment marker. There is no tgg_pk_test_. Your staging key and your production key are indistinguishable by inspection — the environment is the base URL, never the key.

So don't write a guard that infers environment from the key string, and do label the two clearly in your own secret store. Pointing a staging deploy at the production base URL with a production key will not fail loudly; it will just work, against real data.

Registering a webhook

For staffing. Signing, verification code and the retry ladder are in Reference → Webhooks; this is just the setup sequence.

  1. Send us an HTTPS endpoint

    It needs to answer any 2xx within 15 seconds. Do the real work asynchronously — acknowledge first, process after, or you'll trip retries you didn't need.

  2. We generate your signing secret

    You don't choose it. Note that if no webhook URL is configured, events are silently skipped rather than queued — so an unset URL looks exactly like "nothing happened".

  3. Ask us to fire a test delivery

    Cheapest proof that your endpoint, TLS and signature check all work. Two gotchas: it arrives as offer.accepted (there is no distinct test type), and its body is { "test": true, "message": "…", "timestamp": "…" } — no offerId. Check data.test before you dereference an offer payload.

  4. Confirm you verified the signature, not just the status code

    A test that returns 200 from a handler that never checked the signature has proven nothing. Verify against the raw request body — parsing and re-serialising the JSON changes the bytes, and the HMAC will not match.

Rotation has no dual-signing window

When we rotate your secret, the previous one is retained on your record but deliveries are signed with the new secret from that moment on — we do not send two signatures or accept the old one during a grace period.

So make your verifier accept either secret across a rotation, deploy that first, then ask us to rotate, then drop the old one. Rotating before your verifier accepts both means every delivery in between fails its signature check and retries until it dead-letters.

Sandbox & promotion

Your partner organization moves through three stages, and we track four concrete items to get you from one end to the other.

Stage What it means
created Your record exists. Keys can already be issued, and they already work.
sandbox You've proven the integration end to end against staging, including a delivered test webhook.
live We've promoted you, and the date is recorded.

The four items we watch

A webhook URL is configured
An active API key has been issued
A sandbox test webhook was delivered
You've been promoted to live

The stage is a label, not a gate

This is the easiest thing to get wrong about our onboarding. Your key works from the moment your partner organization is active — which is immediately. Nothing checks the stage before serving a request, so a key issued at created can hit production endpoints straight away.

So you're never blocked waiting on promotion — but "we haven't gone live yet" is not a safety net. A staging key pointed at the production base URL acts on production data on day one. Keep the environments separate on your side.

We can see how your integration is behaving

Your partner record carries live counters — offers sent, accepted, declined and pending, your accept rate, webhook deliveries succeeded and failed, how many are sitting in the dead-letter queue, and when we last saw any activity from you. We can also replay a failed delivery on request.

So when something looks wrong, ask before you instrument: it's usually faster for us to read you the delivery history than for you to add logging and discover we never sent it.


Going live

Environments and the last mile

Environments

Two environments, staging and production. They share no data — organizations, events, keys and bookings all exist independently in each, so ask for staging copies of anything you need to test against. Base URLs are in Reference → Base URLs; staging is the same host with a staging. prefix. Staging runs Stripe in test mode: use test cards, never a real one.

The embed loader derives everything from its own src, so switching environments in an embedded integration is one URL swap: staging.my-v2…/embed.js instead of my-v2…/embed.js. Don't mix them — a staging loader with a production event ID simply won't find the event.

Go-live checklist

Worth walking before your first real registration, not after it. The last two items only apply if you're on the Partner API track.

Your production organization ID is in your production config, and your staging one isn't.
Branding is set on your org record — logo, display name, the noun you use for events.
Checkout is enabled on the events you're selling. An event without a checkout configuration shows "registration isn't open".
You've completed one real end-to-end booking on staging, including payment and the confirmation email.
Your booking-complete handler fires your analytics and does something useful with the bookingId.
Parents have a route to self-service — the portal link is in your account menu, or you deep-link into it after checkout.
Your requirement set is configured, so the waivers and forms you're legally relying on are actually being collected.
You've read the status of anything you depend on that isn't marked Live.
Your webhook verifier accepts two secrets, tolerates the test payload, and dedupes on X-TGG-Delivery-Id.
Your production key is stored as a secret, not in a repository, and you know who can rotate it.
Next

Keep going

Ready to build?

Getting started tells you exactly what to ask us for — and there's a copy-paste email at the bottom of it. Or just write to us: an organization ID, an API key, a staging event to test against, or something still marked Preview or Planned.

Contact us