9000INC developer platform

Analytics API V1

Read privacy-safe aggregate analytics from 9000INC products without exposing private account, payroll, invoice, support-content, raw Discord identity, or server-statistics data.

Chart studio

Preview and export a chart

Sample data

Try the chart styles with sample data, or load a public dataset using your scoped API key. Live requests use your normal API quota and the key owner’s website theme.

The key is sent only in the Authorization header to this website. It is not saved by this preview or included in downloads.

Preparing sample chart…

Chart values

Authentication

Send the key as an HTTP Bearer token. Full secrets are displayed only when created or rotated.

Authorization: Bearer 9k_live_...

Versioning

The public API is versioned in the URL. Public endpoints use /api/v1/analytics/.... Existing internal/admin analytics routes remain separate.

Datasets

Privacy-safe endpoints

DatasetEndpointRequired scope
Platform overview/api/v1/analytics/platformanalytics:platform
Game downloads/api/v1/analytics/game-downloadsanalytics:downloads
Advertising/api/v1/analytics/adsanalytics:ads
Giveaways/api/v1/analytics/giveawaysanalytics:giveaways
Games/api/v1/analytics/gamesanalytics:games
Login geography/api/v1/analytics/login-geographyanalytics:geography

Date filters: ?unit=days&amount=30. Public v1 accepts days (max 365), weeks (max 52), or months (max 24). Login geography instead uses ?month=YYYY-MM&granularity=city|region|country and retains the existing privacy threshold.

cURL example

curl -H "Authorization: Bearer $NINEK_API_KEY" \
  "https://9000inc.com/api/v1/analytics/platform?unit=days&amount=30"

Node example

const response = await fetch(
  'https://9000inc.com/api/v1/analytics/platform?unit=days&amount=30&include_charts=1',
  { headers: { Authorization: `Bearer ${process.env.NINEK_API_KEY}` } }
);
if (!response.ok) throw new Error(`Analytics request failed: ${response.status}`);
const { data, charts, presentation } = await response.json();

Shared chart models

Add include_charts=1 to any dataset endpoint to receive chart_schema: "9000inc.chart.v1", a charts array, and the API key owner’s resolved presentation. Existing authentication, privacy filtering, and quotas apply once to the request. Omitting this option keeps the original data response.

Each chart contains its title, labels, numeric series, display, format, range, and coverage. Models contain only data already released by that public dataset. Underlying collection limits still apply; login geography includes only groups released by its existing privacy threshold.

The same renderer used by the website and Discord is available at /analytics/chart-renderer.js. It exports window.NineKCharts in a browser and a CommonJS module in Node. Load it, then render a model:

const scene = NineKCharts.render(charts[0], {
  width: 1280, height: 720, theme: presentation
});
// scene.svg is the exportable SVG source.
// scene.model is the normalized chart model.

Use the preview above for SVG, PNG, and chart JSON downloads. PNG is rendered in your browser from the same SVG. The public API does not expose private Discord server charts or require an npm package.

Scopes

Least-privilege keys

Platform overview
analytics:platform
Game downloads
analytics:downloads
Advertising performance
analytics:ads
Giveaway activity
analytics:giveaways
Game activity
analytics:games
Privacy-safe login geography
analytics:geography

Quotas

Membership-based limits

MembershipPer minutePer day
Free30500
Basic905,000
Premium18025,000
Pro360100,000

Rate-limit information is returned in response headers and the JSON envelope. Quotas are account-wide across all keys, enforced with an atomic account reservation before dataset generation, and membership changes automatically change the active quota without regenerating a key. Rate-limited requests do not extend the lockout window.

Key lifecycle

Keys can be limited to specific datasets, edited later, rotated without changing their scopes, or revoked immediately. Rotation invalidates the previous secret as soon as the new one is issued.

Rate-limit headers

X-RateLimit-Plan, minute/day limit and remaining values, minute/day reset Unix timestamps, and Retry-After on throttled responses are available for client backoff.

Error envelope

Rejected requests return a stable error_code such as missing_api_key, invalid_or_revoked_api_key, scope_denied, rate_limit_exceeded, or quota_accounting_busy, alongside a human-readable message.

Privacy boundary

The public API intentionally excludes raw account IDs, emails, support message content, wallet transactions, invoices, Teams payroll, private room/player identifiers, raw Discord user/server/channel identifiers, and internal server statistics. Login geography keeps the existing distinct-user suppression threshold. Advertising exposes only the verified event ledger created in Patch 674.