A standalone Devvit app that other developers can install to inspect Journey telemetry in chart form.
- Ingestion API endpoint for Journey events with per-project key auth.
- Dashboard charts for funnel, retention cohorts, drop-off heatmap, latency trends, segments, and raw event explorer.
- Project registration and API key rotation endpoints.
- Redis-backed event persistence with bounded reads/writes and degraded in-memory fallback.
- Starter TypeScript + Vite + Hono + React structure.
- Install dependencies.
npm install- Configure app secrets/settings through Devvit settings.
Example snippet from devvit.json:
{
"settings": {
"global": {
"journey_insights_admin_key": {
"type": "string",
"label": "Journey Insights Admin Key",
"isSecret": true
}
}
}
}Set the real secret value with CLI (do not put real values in devvit.json):
npx devvit settings set journey_insights_admin_key "replace-with-strong-admin-key"
npx devvit settings listOptional local fallback for development only:
$env:JOURNEY_INSIGHTS_ADMIN_KEY = "replace-with-strong-admin-key"- Login to Devvit and run playtest.
npm run login
npm run devCreate a project and one API key.
Headers:
content-type: application/jsonauthorization: Bearer <admin-key>whenjourney_insights_admin_keyis configured.
Body:
{
"projectId": "proj_my_game"
}Response includes projectId and apiKey.
Rotate key for an existing project.
Headers:
content-type: application/jsonauthorization: Bearer <admin-key>whenjourney_insights_admin_keyis configured.
Body:
{
"projectId": "proj_my_game"
}Headers:
content-type: application/jsonauthorization: Bearer <project-api-key>x-project-id: <project-id>
Body:
{
"events": [
{
"appId": "example-app",
"projectId": "example-project",
"journeyId": "journey-123",
"eventType": "Journey.Start",
"at": 1760000000000,
"segment": "desktop"
}
]
}Headers:
authorization: Bearer <project-api-key>x-project-id: <project-id>or?projectId=query.
Returns dashboard-ready chart data for the selected project.
This app is designed so each external app pushes telemetry to this app's ingestion endpoint. That gives team-wide cross-app analytics without needing direct read access across native Devvit Journey streams.
Yes, the Devvit Journeys pattern works here, but you need one adapter step:
thread x-devvit-journey-id from your client request into a server route, then forward
it to this app's POST /api/ingest payload as journeyId.
Client example (your app):
import { telemetry } from '@devvit/analytics/client/reddit';
export async function submitScore(score: number): Promise<void> {
const journeyId = telemetry.getActiveJourneyId();
await fetch('/api/score', {
method: 'POST',
headers: {
'content-type': 'application/json',
...(journeyId ? { 'x-devvit-journey-id': journeyId } : {}),
},
body: JSON.stringify({ score }),
});
}Server adapter example (your app backend):
app.post('/api/score', async (req, res) => {
const journeyIdHeader = req.header('x-devvit-journey-id');
const journeyId = typeof journeyIdHeader === 'string' ? journeyIdHeader : '';
const score = Number(req.body?.score ?? 0);
await fetch(`${process.env.JOURNEY_INSIGHTS_URL}/api/ingest`, {
method: 'POST',
headers: {
'content-type': 'application/json',
authorization: `Bearer ${process.env.JOURNEY_INSIGHTS_PROJECT_KEY}`,
'x-project-id': process.env.JOURNEY_INSIGHTS_PROJECT_ID ?? '',
},
body: JSON.stringify({
events: [
{
appId: 'your-app-id',
projectId: process.env.JOURNEY_INSIGHTS_PROJECT_ID,
journeyId: journeyId || `fallback-${Date.now()}`,
eventType: 'Journey.End',
at: Date.now(),
complete: true,
win: true,
score,
action: 'submit_score',
actionDetails: 'score submitted from gameplay flow',
},
],
}),
});
res.json({ ok: true });
});Notes:
- This app does not provide
/api/score; your backend route is the adapter. - Keep
eventTypealigned with actual user commitment points. - Do not send PII in
actionoractionDetails.
- Open Journey Insights dashboard.
- Enter Project ID and click "Create Project + Key" (or paste existing ID/key).
- Paste the generated ID/key into your app's telemetry sender.
- Open the same dashboard, keep those credentials filled in, and charts load automatically.
- Add per-project quotas and request metering.
- Add role-based admin auth integration.
- Add CSV export and schema versioning.