Docs
Connect everything once.
Prodline brings numbers and goals into your projects on its own. Here is every way in, and how to set each one up so you never refresh a dashboard again.
Three ways in
Everything lives on the project: open it and tap Connection. You can combine all three on one project; numbers from every source add up, and revenue that two sources both count (RevenueCat and App Store Connect) is only counted once.
Integrations
Open the project → Connection → Integrations and pick a service. Keys are stored in the iOS Keychain on your iPhone and sent only to the service they belong to. Numbers count from the day the project started, so older sales or views don't inflate them.
Revenue and stores
Downloads, proceeds and your star rating
You'll need
- Private key (.p8) kept in your Keychain
- Issuer ID
- Key ID
- Vendor number
- App Apple ID
- Ratings storefront optional
Set up
- In App Store Connect open Users and Access → Integrations → App Store Connect API.
- Create a team key with the Finance role (or Sales and Reports). Download the .p8 file: Apple only lets you do that once.
- Copy the Issuer ID (above the key list) and the key's Key ID.
- Vendor number: Payments and Financial Reports, top left. App Apple ID: your app → App Information.
- Open the .p8 file in Files or a text editor and paste its whole contents as the private key.
- Apple publishes sales a day later, so downloads lag about a day.
Revenue, MRR, subscribers and trials
You'll need
- Secret API key (v2) kept in your Keychain
- Project ID
Set up
- In RevenueCat open Project settings → API keys → + New secret API key.
- Choose API version 2 and give Charts & metrics read access (overview and charts). Nothing else.
- The project ID is in the address bar: app.revenuecat.com/projects/<this part>/…
- RevenueCat already counts App Store purchases, so with both connected revenue comes from RevenueCat only.
Revenue and sales
You'll need
- Restricted key kept in your Keychain
Set up
- In the Stripe Dashboard open Developers → API keys → Create restricted key.
- Give it Read access to Balance (balance transactions). Leave everything else at None.
- Revenue is what customers paid since the project started, minus refunds.
Revenue and orders
You'll need
- API key kept in your Keychain
- Store ID optional
Set up
- In Lemon Squeezy open Settings → API → + to create a key.
- The store ID is optional: leave it empty to count every store on the account.
- Revenue is paid orders since the project started, in USD.
Revenue and sales
You'll need
- Access token kept in your Keychain
Set up
- On Gumroad open Settings → Advanced. Under Applications, give it a name and icon, and enter http://127.0.0.1 as the Redirect URI (it isn't used).
- Click Create application, then Generate access token, and paste the token here. It doesn't expire until you revoke it.
- Revenue is sales since the project started, minus refunds.
Revenue and orders
You'll need
- Admin API access token kept in your Keychain
- Store address
Set up
- In your Shopify admin open Settings → Apps and sales channels → Develop apps, and create an app.
- Under Configuration give the Admin API the read_orders scope, then install the app.
- Reveal the Admin API access token once (it starts with shpat_) and paste it here.
- Revenue is what paid orders brought in since the project started, minus refunds and cancellations.
Revenue and sales
You'll need
- API key kept in your Keychain
- Environment optional
Set up
- In Paddle open Developer tools → Authentication → API keys and create a key with read access to transactions.
- Using the sandbox? Type sandbox under Environment.
- Revenue is completed transactions since the project started, before Paddle's fees.
Revenue and orders
You'll need
- Organization access token kept in your Keychain
- Organization ID optional
Set up
- In Polar open Settings → Developers → New token, and give it the orders:read scope.
- The organization ID is optional: leave it empty to count every organization the token sees.
- Revenue is paid orders since the project started, minus refunds.
Analytics
Visitors and pageviews
You'll need
- Stats API key kept in your Keychain
- Site
- Server optional
Set up
- In Plausible open your account settings → API keys → New API key, and pick Stats API.
- Site is the domain exactly as it appears in your Plausible dashboard.
- Self-hosting? Put your server's address in Server.
Visitors and pageviews
You'll need
- API key kept in your Keychain
- Website ID
- API address optional
Set up
- Umami Cloud: Settings → API keys → Create key. The website ID is under Settings → Websites → Edit.
- Self-hosted: use your server's API address (https://your-umami.com/api) and an API token.
Visitors and pageviews
You'll need
- API token kept in your Keychain
- Site ID
Set up
- In Fathom open Settings → API and create a token with access to the site (or all sites).
- The site ID is the code in your embed snippet (data-site="ABCDEFG") and under Settings → Sites.
Visitors and pageviews
You'll need
- Personal API key kept in your Keychain
- Project ID
- Host optional
Set up
- In PostHog click your avatar → Settings → Personal API keys → Create, with Query read access.
- The project ID is in the address bar: us.posthog.com/project/<this number>.
- On EU Cloud or self-hosted? Put the address under Host, e.g. https://eu.posthog.com.
- Visitors are unique people with a pageview, pageviews every $pageview event.
Visitors and pageviews
You'll need
- API key kept in your Keychain
- Website
- User ID
Set up
- In Simple Analytics open Account settings → API keys and create one. The user ID is shown on the same page.
- Website is the domain exactly as it appears in your dashboard.
Hosting
Deploys while you build
You'll need
- Access token kept in your Keychain
- Project ID or name
- Team ID optional
Set up
- In Vercel open Account settings → Tokens and create one, scoped to the team that owns the project.
- The project ID is under Project → Settings → General (prj_…); the project's name works too.
- For a team project, add the team ID from Team settings → General.
- Counts deploys since the project started: a good pulse while you build. Vercel has no public analytics API yet.
Deploys while you build
You'll need
- Personal access token kept in your Keychain
- Site ID
Set up
- In Netlify open User settings → Applications → Personal access tokens → New access token.
- The site ID is under Site configuration → General → Site details (Site ID).
- Counts successful deploys since the project started. Netlify has no public analytics API yet.
Newsletters
New newsletter subscribers
You'll need
- API key (v4) kept in your Keychain
Set up
- In Kit open Settings → Developer → API keys (v4) and add a key.
- Counts active subscribers who joined since the project started.
New newsletter subscribers
You'll need
- API key kept in your Keychain
Set up
- In Buttondown open Settings → API and copy your API key.
- Counts subscribers who joined since the project started.
New newsletter subscribers
You'll need
- API key kept in your Keychain
- Publication ID
Set up
- In beehiiv open Settings → API → Create new API key.
- The publication ID is on the same page (pub_…).
- Counts active subscribers who joined since the project started.
GitHub
Open the project → Connection → GitHub and enter the repository as owner/repo. A token is optional: add one for private repositories and a higher rate limit (it stays in the Keychain). Prodline reads the repo every 10 minutes, counts commits toward Momentum and your streak, and turns the README and open issues into goal suggestions.
prodline.json: your plan in the repo
Add prodline.json at the root of the repository and it becomes the project's plan: exactly its checkpoints and goals, nothing else. Mark a goal done in a commit and it ticks itself in the app.
{
"version": 1,
"checkpoints": [
{ "day": 4, "title": "Core loop" },
{ "day": 10, "title": "Onboarding" }
],
"goals": [
{ "id": "streak-card", "title": "Shareable streak card", "day": 4, "done": true },
{ "id": "paywall", "title": "Paywall screen", "day": 10 },
{ "id": "signups-50", "title": "Reach 50 signups", "day": 10, "metric": { "key": "signups", "target": 50 } }
]
}
day counts from the project's start (day 1 = start date), so the plan follows schedule changes. A goal lands on the first checkpoint on or after its day. "due": "YYYY-MM-DD" works for fixed dates.
- Without
checkpoints, the goals' days become the checkpoints.
metric goals tick themselves when the number reaches the target.
- Keep
ids stable; a missing file clears its open goals, an invalid one is reported and existing goals are kept.
- Building with Claude Code? The GitHub guide in the app has a prompt to copy into
CLAUDE.md, so it keeps the plan current and ticks goals as it ships.
Issues and milestones
Without prodline.json, issues in a GitHub milestone or labeled prodline become goals and tick off when closed. A milestone's due date picks the checkpoint; without one, the Nth milestone maps to the Nth checkpoint. Pull requests are ignored.
Instant updates
By default the app checks the repo every few minutes. With a webhook, a push reaches your iPhone within seconds, even when the app is closed.
- In the app: project → Connection → Instant updates. It shows a payload URL and a secret, each with a copy button.
- On GitHub open the repo → Settings → Webhooks → Add webhook. You need admin access to the repo.
- Paste the payload URL and the secret. Content type:
application/json.
- Leave “Just the push event” selected and click Add webhook. GitHub sends a test ping right away.
The relay only passes the webhook ID, repository name, event type and number of commits on to your device. Turn it off under Me → Configuration by typing off as the relay address. Details in the privacy policy.
Your own endpoint
For anything without an integration, point the project at one HTTPS address: project → Connection → Your own endpoint. Prodline sends
GET <endpoint>?since=<ISO-8601>
Authorization: Bearer <api key> (left out when you set no key)
Accept: application/json
since is the newest point Prodline already has; return only history after it. The key is yours to create and stays in the Keychain.
Response
{
"schemaVersion": 1,
"asOf": "2026-10-04T12:00:00Z",
"metrics": [
{ "key": "visits", "value": 8849 },
{ "key": "social_views", "value": 21114 },
{ "key": "revenue", "value": 529.89, "unit": "USD" },
{ "key": "signups", "value": 398 }
],
"history": [
{ "asOf": "2026-10-04T11:00:00Z", "metrics": [ { "key": "visits", "value": 8790 } ] }
]
}
- Values are running totals (all-time), not deltas.
visits, social_views and revenue are built in; any other key shows up as its own number.
history is optional, ideally hourly. Re-sending points is harmless.
// Node / Express
app.get("/api/prodline", (req, res) => {
if (req.get("Authorization") !== `Bearer ${process.env.PRODLINE_KEY}`) return res.status(401).end();
res.json({
schemaVersion: 1,
asOf: new Date().toISOString(),
metrics: [
{ key: "visits", value: totals.visits },
{ key: "revenue", value: totals.revenue, unit: "USD" },
],
});
});
Goals
Add a goals array to the same response. When present it is the full list.
"goals": [
{ "id": "onboarding", "title": "Onboarding flow live", "checkpoint": 3, "done": false },
{ "id": "launch-post", "title": "Launch post published", "due": "2026-10-08T00:00:00Z" },
{ "id": "signups-500", "title": "500 signups", "checkpoint": 4, "metric": { "key": "signups", "target": 500 } }
]
checkpoint is the 1-based position in the project's deadlines; due places a goal on the first deadline on or after a date. A checkpoint whose goals are all done completes by itself, with XP and streak as if you tapped it.
GitHub as the endpoint
No server? A GitHub Action can publish the file for you. In the app, the endpoint page's “Use GitHub as the endpoint” guide has the workflow to copy into .github/workflows/. On every push and every 6 hours it writes metrics.json to a metrics branch; use https://raw.githubusercontent.com/<owner>/<repo>/metrics/metrics.json as the endpoint, with no key. Works for public repositories.
Polling and errors
- Every 30 seconds while the app is open (Me → Configuration → Live refresh), and in the background when iOS allows, roughly every 15 minutes.
- Only projects in their build or observe phase are polled.
401/403 show “API key rejected”, 404 “Endpoint not found”; 429 honors Retry-After; server errors and timeouts back off from 30 seconds up to 15 minutes.
A seamless setup
- Start with money. Connect where revenue lands first (Stripe, RevenueCat, App Store Connect…): it's the number that decides keep or let go.
- Add one traffic source. Plausible, Fathom, PostHog, Simple Analytics or Umami for visits; YouTube, TikTok, Instagram, Threads or Bluesky if that's where your audience is.
- Link the repo and add
prodline.json. Your plan lives next to your code, and commits keep the streak alive without opening the app.
- Turn on instant updates. One webhook, and goals tick seconds after you push.
- Add the widgets. Long-press the Home Screen → Edit → Add Widget → Prodline. The deadline Live Activity appears on its own in the last four hours before a checkpoint.
- Pick your three numbers. With more than three, long-press a number on the project or the Data tab to swap it.