Skip to main content
Before you point production traffic at Qyren, exercise the full loop with a sandbox key. This page covers the qyr_test_ vs qyr_live_ distinction, how to verify events landed, and how to debug the most common errors.

Two key prefixes

Every API key Qyren issues starts with one of two prefixes: Both keys are tied to the same game_id, so the schema and request shapes are identical. You can switch between them by changing only the Authorization header.

Getting a test key

In the dashboard, open Settings → API Keys. There’s a “Generate test key” button alongside the live key controls. Test keys are free, you can have multiple, and you can revoke and regenerate at will. Keep test and live keys separate in your environment config. A common pattern:

Verifying events landed

To confirm events made it to Qyren, open the dashboard at https://app.qyren.ai and go to the Events view for your game. It shows the most recent events received, including event type, player ID, and arrival time. Use it during integration to confirm your batching, ULID generation, and field formatting are correct. Events typically appear within a few seconds of acceptance.

A reasonable test plan

  1. Send one event. Pick session_start — minimal required fields. Confirm 202 Accepted.
  2. Send a batch with one bad event. Make one event missing a required field (e.g., a purchase without revenue_usd). Confirm 207, inspect the errors[] array, confirm only the bad event was rejected.
  3. Import 2–3 offers. Confirm 200 OK with the right imported count.
  4. Request a recommendation. Confirm you get an ordered offer list back.
  5. Send offer_impression events for each returned offer.
  6. Send a purchase event for one of them.
  7. Open the Events view in the dashboard. Confirm everything you sent shows up in the order you expect.
If all seven pass with a qyr_test_ key, swap in your qyr_live_ key and you’re ready for production traffic.

Common 400 errors

These are the failures you’ll hit most often during integration. Every one of them surfaces in the errors[] array of a 207 response (or the details of a 400).

event_id: must be a valid ULID

Your event_id isn’t a 26-character Crockford Base32 string. UUIDs and incrementing integers are not accepted. Use a ULID library — every modern language has one. Optionally prefix with evt_ (the ULID is parsed from after the last underscore).

event_time: more than 7 days in the past / more than 7 days in the future

Server clock skew, or you’re replaying very old logs. Qyren rejects anything outside ±7 days of its server clock to keep analytics windows clean. Sync your server time (NTP), and if you really need to backfill ancient data, email [email protected] for a one-shot import.

properties.<field>: required for <event_type> events

You’re missing one of the per-type required properties. Check Event Schema for the exact list. The most common offenders:
  • purchase missing is_first_purchase (it’s a boolean — send false, not omit it).
  • currency_earned / currency_spent missing balance_after.
  • offer_impression missing position.

player_id: must be 1-64 chars, alphanumeric/underscore/hyphen only

Spaces, dots, colons, or @ in your player_id. Hash or remap to a clean opaque ID.

geo.country: must be a valid ISO 3166-1 alpha-2 code

You sent usa, united states, or US (trailing space). It must be exactly two uppercase letters: US, DE, JP.

Debugging the 207 response

Whenever you see 207 Multi-Status, walk the errors[] array. Each entry has:
  • event_index — position in the array you sent. Match it back to your local buffer.
  • event_id — the failing event’s ID, if it had one.
  • field — which field failed.
  • error — human-readable reason.
Fix the bad events in your buffer, retry only those, and leave the accepted ones alone (re-sending them is harmless but wastes a slot in the next batch).

When things still don’t work

Email [email protected] with:
  • Your game_id.
  • A sample of the request body that failed (redact the Authorization header).
  • The full response body.
You’ll usually hear back the same day.