Going live

Every project has Sandbox and Live. They share nothing: definitions, players, points, purchases, webhook endpoints and API keys all belong to one environment.

So going live is not a deployment. Your code does not change. There is no environment parameter and no second hostname, and the API key decides where a request lands. What you change is the key, after rebuilding everything that key will find.

The one thing both share is the project's default language and default time zone, set when the project was created. A window that turns over at midnight in Sandbox turns over at the same moment in Live.

1. Rebuild every definition in Live

  • Recreate events and their properties, attributes, segments, missions, mission collections, streaks, leaderboards, catalog items, marketplace items, marketplace collections and points valuations.
  • Most create screens let you tick Live alongside Sandbox, and make the same key in both: events, attributes, segments, missions, streaks, leaderboards, marketplace items and points valuations.
  • Catalog items and collections are one environment at a time. They do not offer it.
  • Do catalog items before marketplace listings. A listing can only be created where the catalog item it hands over already exists.
  • Check the result. After creation each environment's copy is its own thing, and editing one does not touch the other.

No public endpoint reads a definition back. You cannot list the event, attribute or catalog item keys that exist in an environment, but sending rejects on exactly those: event.not_found, event.inactive, player_attribute.not_found, player_attribute.inactive. The first time you learn something is missing from Live will be a refused event.

2. Create a separate Live key

  • On the API keys screen, switch to Live and create one there.
  • Store it when it is created. You see it once. A live key is gem_live_ plus 64 hex characters, a sandbox key gem_sbox_ plus 64.
  • You cannot promote the sandbox key. A key belongs to one environment for life.
  • Keep it on a server you control.

One key is full write access to its environment, including POST /v1/points/adjustments, which creates points out of nothing. It never belongs in a browser, a mobile app or a game client.

Revoking a key takes effect at once. A revoked key, an unknown key, a missing Authorization header and a malformed one all give the same 401 auth.api_key_invalid, so a failing deploy will not tell you which it was.

3. Set up the Live webhook endpoint

  • On the Webhooks screen, switch to Live and add the endpoint with its own subscriptions.
  • Give it an absolute http or https URL, at most 2,048 characters, and at least one event.
  • Do not point it at localhost or a private address. Those are refused.
  • Register the final URL. A redirect is not a delivery.
  • One endpoint per environment receives CatalogItemFulfillmentRequested. The three notifications go to as many endpoints as you like.
  • Store the new signing secret. It starts whsec_, differs from the sandbox one, and is shown once.

4. Test the endpoint before real traffic

  • Press Ping on the Live endpoint. It sends one signed delivery the way real traffic goes, so an accepted ping proves your signature check agrees with ours.
  • Read the result. A refusal comes back with your endpoint's own status code and error text. A 4xx from the dashboard means the request to Gemifier was wrong, not that your endpoint refused.
  • Confirm your receiver checks against the Live secret. One with the sandbox secret hard-coded answers 401 on every live delivery, and a 401 is the one answer that is never retried.
  • Ping as often as you like. It is never retried, it ignores the subscriptions and whether the endpoint is switched on, and it carries a new delivery id each time.

Verifying signatures has what your receiver has to match.

5. Switch the key and watch the first hour

Swap gem_sbox_... for gem_live_... in your backend's configuration and deploy. That is the switch. Keep the sandbox key working, because it is where you will reproduce the first live problem.

A real player, in Live
curl -X POST https://api.gemifier.io/v1/missions \
  -H "Authorization: Bearer gem_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "playerId": "player-42" }'

Three things say the integration is intact. The missions come back non-empty, so your live missions exist and the player is now in them. One real event moves progress when you read them again. A catalog_item.fulfillment_requested webhook reaches your live receiver and its signature checks out.

Know before you launch

  • Sixteen requests at once. Not per second, in flight at the same time, with 8 more allowed to wait and the rest refused with 429. It belongs to the organization, so Sandbox and Live share it. See Errors.
  • Nothing pages. GET /v1/points/transactions without a Take returns a player's whole ledger, which grows without bound. Send a Take.
  • The same delivery can arrive twice. deliveryId is the same on every attempt, so de-duplicate on X-Gemifier-Delivery and treat a repeat as nothing. Nothing promises an order between two events about the same player. See Retries.
  • A 4xx other than 408 or 429 ends a delivery on the first attempt. Everything else is retried for a while. Answer 503, never 404, while you are mid-deploy.
  • Given-up deliveries can be recovered, unevenly. catalog_item.fulfillment_requested and mission.completed can be sent again from the dashboard. streak.milestone_reached and leaderboard.period_closed cannot.
  • Decide who watches the delivery backlog. Nothing alerts you.
  • There is no way to erase a player. POST /v1/players creates one, and sending an event, setting an attribute or reading their missions creates one too, but nothing public deletes one. Plan for erasure requests before you have them.
  • There is no health endpoint. GET / on api.gemifier.io is a 404. Do not point an uptime check at it.

Next

On this page