/ Documentation

Overview

Metriquality ingests three signal streams from your studio — developer velocity (Jira/GitHub), player sentiment (Discord), and player telemetry — correlates them against live competitor market signals, and emits a single executable recommendation with measured impact (incremental lift measured via holdout / geo-split where available).

This guide walks from zero to your first recommendation in three steps. You'll need: your studio's credentials (delivered by email at signup), and admin access to your Jira/GitHub org and Discord server.

Step 1 — Connect Webhooks

Each credential email includes three webhook endpoints. Configure whichever signals you want to use:

Jira

In Jira: Project Settings → Webhooks → Create Webhook. Set the URL to your jira_endpoint and enable events: Sprint started, Sprint closed, Issue resolved. Set the secret header X-Jira-Signature to your jira_webhook_secret.

GitHub

In your repo: Settings → Webhooks → Add Webhook. Set the Payload URL to your github_endpoint. Content type: application/json. Secret: your github_webhook_secret. Events: Pull requests, Issues.

Discord

In your server: any bot or webhook integration that can POST messages to your discord_endpoint with the header Authorization: Bearer <discord_webhook_secret>. Each message is run through sentiment analysis automatically.

Step 2 — Ingest Telemetry

POST player events to your ingest endpoint. Your studio_portal_key (spk_...) is the auth token. Include your game's game_id (from the studio portal) and the current build_tag:

POST /api/ingest
Authorization: Bearer spk_...
Content-Type: application/json

{
  "game_id":    "550e8400-e29b-41d4-a716-446655440000",
  "build_tag":  "v2.4.1",
  "player_id":  "player_abc123",
  "event_type": "session_start",
  "event_ts":   "2026-05-29T09:00:00Z"
}

NoteEvents are written to ClickHouse. The recommendation engine aggregates the last 7 days of events per build tag. Send events for every session start and key in-game milestone.

Step 3 — Read Your First Recommendation

Once enough telemetry has accumulated (24–48 hours), call the recommendations endpoint:

GET /api/games/{game_id}/recommendations/latest?build_tag=v2.4.1
X-Metriquality-Portal-Key: spk_...
{
  "recommendation_type": "aggressive_uacq",
  "confidence_score": 0.87,
  "data_tier": "tier_2_telemetry",
  "is_algorithmic_fallback": false,
  "upgrade_prompt": null,
  "confidence_degradation_reason": null,
  "generated_at": "2026-06-06T09:00:00.000Z",
  "rationale": "Rival Arena: Champions CCU down 38% in 48h. Your retention holding at 0.94. Acquisition window open.",
  "execution_payload": {
    "action_type":    "increase_ad_spend",
    "target_metric":  "marketing_budget",
    "suggested_value": 1.5,
    "priority":       "high"
  },
  "log_id": "a1b2c3d4-..."
}

is_algorithmic_fallbacktrue when the AI inference engine was unavailable and the recommendation came from deterministic rules. Outbound dispatch is suppressed for fallback recommendations — do not auto-execute them. Surface this flag in any automated integration so operators know the AI was offline.

data_tier — One of tier_0_no_data, tier_1_scraped_only, tier_2_telemetry, tier_3_velocity. Confidence scores are hard-capped at 0.40 for Tier 0/1. When upgrade_prompt is non-null the engine recommends integrating the telemetry SDK to unlock higher-confidence recommendations.

confidence_degradation_reason — Non-null when the studio crisis gate fired (own-game retention declining). The gate prevents aggressive_uacq during a retention crash and caps confidence. Surface this in your UI so operators understand why the score is lower than expected.

generated_at — ISO 8601 timestamp of when the recommendation was computed. Recommendations reflect the correlation snapshot at that instant. Re-call the endpoint every 15–30 minutes during active market windows; market conditions can shift faster than that during major competitor incidents.

Save the log_id. You'll use it to submit your outcome 7 days later so the engine can compute the measured impact (an internal before/after effect-size estimate; directional unless you ran a holdout).


Authentication

All studio-facing API endpoints require your studio portal key (spk_... prefix). Pass it in the X-Metriquality-Portal-Key header.

X-Metriquality-Portal-Key: spk_abc123...

Keys are tenant-scoped. Requests using a valid key for a different tenant return 403 Forbidden. Missing or invalid keys return 401 Unauthorized.

WarningTreat your portal key as a secret. It authorises data export and competitor watchlist mutations. Rotate it from your studio portal if compromised.

Studio Portal API

GET /api/client/portal

Returns the full dashboard payload: games list, latest recommendations per game, competitor vulnerability scores, and signal summaries.

POST /api/client/portal/games

Register a new game under your studio.

{ "title": "My Game", "genre": "Action", "platforms": ["Steam"] }
DELETE /api/client/portal/games/:game_id

Remove a game from monitoring.

GET /api/client/portal/competitors

List your studio's competitor watchlist.

POST /api/client/portal/competitors

Add a rival to your watchlist. The poller will pick it up within ~30 minutes.

{ "steam_app_id": "730", "platform": "steam" }
DELETE /api/client/portal/competitors/:steam_app_id

Remove a rival from your watchlist.

Telemetry Ingestion

POST /api/ingest

Ingest a player event. Events are written to ClickHouse and aggregated into velocity, retention, and CCU signals for the recommendation engine.

FieldTypeRequiredDescription
game_idUUIDYesYour game's ID from the studio portal
build_tagstringYesSemver of current build — e.g. v2.4.1
player_idstringYesStable anonymous player identifier
event_typestringYessession_start | session_end | custom event name
event_tsISO 8601YesClient-side event timestamp
metadataobjectNoArbitrary key-value pairs (max 10 keys)

Noteplayer_id is used to compute distinct player counts (units) and CCU. It is hashed on receipt and never stored in plaintext. Do not send PII.

Recommendations

GET /api/games/:game_id/recommendations/latest

Returns the current recommendation for a game. Combines live telemetry, competitor signals, and market estimates. Responds in under 2 seconds; falls back to a deterministic matrix if inference times out.

Query parameters

ParamRequiredDescription
build_tagYesCurrent build semver — e.g. v2.4.1
tenant_idNoInferred from portal key if omitted

Recommendation types

TypeMeaning
aggressive_uacqCompetitor distress + your retention holding → ramp user acquisition now
review_bomb_containmentSentiment crisis + stable retention → pause feature rollout, monitor
change_freezeExternal market chaos → lock releases, do not ship
no_actionNo significant signal → continue monitoring

Response headers

HeaderDescription
X-Metriquality-Log-IDUUID identifying this recommendation. Pass to outcome submission.
X-Metriquality-Recommendation-Staletrue if market context timed out — recommendation based on cached signals
X-Data-Statusready | insufficient | stale

Market Context

GET /api/games/:game_id/market-context

Returns estimated unit sales for your competitor watchlist alongside your own game's first-party actuals. Own-game data is sourced from your telemetry events — it is never an estimate.

{
  "own_game": {
    "game_id":        "550e8400-...",
    "title":          "My Game",
    "units":          84200,
    "ccu_peak":       3100,
    "is_estimate":    false,
    "data_source":    "first_party_telemetry",
    "confidence":     "measured"
  },
  "competitor_estimates": [
    {
      "steam_app_id":           "730",
      "competitor_name":        "Rival Arena: Champions",
      "total_estimated_units":  420000,
      "is_estimate":           true,
      "confidence":            "medium",
      "coverage_score":        0.74
    }
  ]
}

NoteCompetitor estimates use the Boxleiter model calibrated against confirmed publisher-disclosed milestones. Steam-only. Console scrapers are running; console estimation is not yet available.

Outcomes

Submit metric deltas 7 days after executing a recommendation. Metriquality runs a before/after significance test automatically and returns a measured-impact estimate (lift evidence — directional unless you ran a holdout / geo-split).

POST /api/recommendations/:log_id/outcome
{
  "measured_retention_delta": 4.2,   // percentage points
  "measured_velocity_delta":  null,   // null if not measurable
  "pre_retention":            0.88,
  "cohort_size":              1200
}

The response includes p_value, confidence_level, and observed_effect ("lift" | "regress" | "neutral" | "insufficient_signal"). The p-value is an internal effect-size indicator, not proof of causation.

NoteYou don't have to submit outcomes manually. Metriquality's auto-outcome computer runs nightly and computes results automatically for completed recommendations with sufficient post-action data. Manual submission just gets you the result sooner.

Webhooks

All webhook endpoints are provisioned at signup. Secrets are per-tenant and rotatable from the studio portal.

EndpointAuth headerEvents captured
/api/jira/:tenant_idX-Jira-Signature: sha256=...Sprint open/close, issue resolved
/api/v1/webhooks/github/:tenant_idX-Hub-Signature-256PR merged, issue closed
/api/discord/:tenant_idAuthorization: Bearer ...Messages → sentiment analysis
/api/webhooks/crm/:tenant_idX-Webhook-Secret or provider signatureStripe, Shopify, HubSpot sales events

NoteAll webhook endpoints are idempotent. Duplicate deliveries (same X-GitHub-Delivery or equivalent) are deduplicated and ignored.

Data Export

GET /api/pov/export/:tenant_id

Exports your complete recommendation history, outcomes, playbook definitions, and raw signals in GS-CompInt-2026 format. Requires your spk_ portal key — cross-tenant requests return 403.

Responses carry the header X-GS-CompInt-Version: GS-CompInt-2026. The export is yours to keep — no Metriquality dependency required to read or validate it.


The Open Competitive Intelligence Standard

GS-CompInt-2026 is an open data standard for game studio competitive intelligence. It specifies a portable, vendor-neutral format for competitor incidents, studio outcomes, correlation signals, and playbook definitions.

Any tool that can read JSON can read a GS-CompInt-2026 export. You're not locked in to Metriquality's platform to use your own data.

Schema

A GS-CompInt-2026 document is a JSON object with four top-level fields:

{
  "version": "GS-CompInt-2026",
  "incidents": [ /* MarketIncident[] */ ],
  "outcomes": [ /* RecommendationOutcome[] */ ],
  "correlation": [ /* CorrelationSnapshot[] */ ],
  "playbooks": [ /* PlaybookDefinition[] */ ]
}

MarketIncident

{
  "competitor_game_id": "string (UUID)",
  "competitor_build_tag": "string (semver)",
  "incident_type": "patch_day | server_outage | content_drop | live_event | emergency_fix | api_breaking",
  "source_ts": "ISO 8601"
}

RecommendationOutcome

{
  "log_id": "string (UUID)",
  "recommendation_type": "string",
  "measured_retention_delta": "number | null",
  "p_value": "number | null",
  "confidence_level": "number | null",
  "observed_effect": "lift | regress | neutral | insufficient_signal | null"
}

CorrelationSnapshot

{
  "game_id": "string (UUID)",
  "build_tag": "string (semver)",
  "velocity_dau_pct": "number",
  "retention_inverse": "number",
  "sentiment_score": "number",
  "queried_at": "ISO 8601"
}

Discovery Endpoint

Third-party tools can discover the current schema version without cloning this repo:

GET https://metriquality.se/.well-known/gs-compint-2026.json

// Response header:
X-GS-CompInt-Version: GS-CompInt-2026

Validator CLI

Validate any GS-CompInt-2026 document without a Metriquality account:

# Via npm
npx gs-compint-validate path/to/export.json

# Via Metriquality's built-in script
npm run validate-outcome -- path/to/export.json

Exit codes

CodeMeaning
0Valid GS-CompInt-2026 document
1Invalid — schema violations printed to stderr
2Usage error — no file provided or file not found

Open-Source Outcome Validator

The outcome validator runs a Welch's t-test on pre/post recommendation metric deltas to estimate whether an observed change is a measurable effect — or could plausibly be explained by random variance. This is an internal effect-size indicator, not proof of causation; a single-cohort before/after test is directional unless you ran a holdout / geo-split control.

The math is open. You can audit it, run it locally, or integrate it into your own data warehouse. No Metriquality account required.

Usage

npm run validate-outcome -- export.json

# Or pipe a JSON document directly:
cat export.json | npx gs-compint-validate

The validator reads outcomes[] from a GS-CompInt-2026 export and prints a verdict per outcome:

 log_id: a1b2c3... LIFT                p=0.031  retention_delta=+4.2pts
~ log_id: d4e5f6... INSUFFICIENT_SIGNAL  p=0.112  cohort below minimum
 log_id: g7h8i9... REGRESS              p=0.008  delta in wrong direction

Statistical Model

Welch's t-test is used rather than Student's t-test because it does not assume equal variance between the pre-action and post-action populations. This is appropriate for game analytics where pre/post sample sizes and variance often differ.

Inputs

  • pre_retention — baseline retention rate before the recommendation was executed
  • measured_retention_delta — observed change in retention after 7 days
  • cohort_size — number of players in the measurement window

Thresholds

observed_effectp-valueMinimum cohort
lift< 0.05 (positive direction)30+ players
insufficient_signal≥ 0.05Any
regress< 0.05 (wrong direction)30+ players

Limitations — When Not to Use This Test

Warning — Correlation ≠ CausationThe t-test tells you whether the delta is statistically significant. It does not prove that the recommendation caused the change. Confounding variables (seasonal events, competitor news, platform updates) can produce significant p-values for reasons unrelated to your action.

  • Cohort size < 30 — the test has insufficient power and results are unreliable. The validator will return insufficient_signal.
  • Measurement window < 7 days — behavioural changes take time to manifest in retention metrics. Submit outcomes after the full window.
  • Multiple simultaneous changes — if you shipped a patch and ran a UA campaign simultaneously, you cannot attribute the delta to either independently.
  • Non-normal distributions — if your player base has extreme outlier behaviour (e.g. whales dominating session length), the t-test's normality assumptions may not hold. Check your distribution first.
  • Velocity delta — DAU velocity is not computed by the retrospective validator because the pre-action baseline cannot be reliably reconstructed from retention-only data. This field is always stored as null.

NoteThe validator follows the honesty gate principle: when data is insufficient, it skips the computation entirely rather than returning a zero or a confident-looking number. An empty result is always preferable to a fabricated one.