server/metrics.ts to fill in; the metric list, its units and its
breakdowns are yours to edit afterwards.
The manifest entry
tappify.extension.json instead — the
$schema line gives your editor completion and validation, and
tappify extension doctor checks the result.
Declaring metrics needs the
metrics:write scope. At most 50 metrics.
A series contribution is what puts the metric on a chart. Its metric must be one you declare
here, and its chart is one of the host charts in
Pages and slots.
The handler
createTappifyHandler routes POST /tappify/metrics to your metrics handler. The request
carries the window Tappify wants and the metric keys it is asking about.
[ISO timestamp, number], and Tappify truncates each one to the hour it falls in
before storing it, so two points in the same hour under the same breakdown are one row. Return
one entry per breakdown: two dimensions values means two entries, each with its own points.
The window is not always your full backfill. A metric that already has points is asked for from
its newest bucket onward; one with none is asked for its declared backfillDays, and the whole
window is clamped to ninety days.
What Tappify checks on every sync
A response that fails any of these writes no points and the run is marked failed, with the first
three problems named on the run. Owners read the failed run, its attempts and your status code on
the extension’s page in their workspace; your Runtime page counts the installs whose last sync
could not reach you.
Retries, and when a metric goes stale
A failed pull is retried three times, waiting 30 seconds, then 2 minutes, then 10 minutes. All four attempts are one run, so the run carries the attempt count; after the last one the run is failed and the next scheduled sync starts fresh. A metric with no successful sync in 24 hours is stale. Its points stay and the line is still drawn, dashed, withLast synced 3 days ago beside it in the chart legend and the same reading
on the install’s sync health panel.
Owner credentials
When your metrics come from a service the owner pays for, declare what you need and Tappify collects it on the install screen, stores it, and sends it with every call.request.credentials on every call Tappify makes to you, keyed by each
field’s name. They are never sent to a browser and never sent to anyone else. A field is
text, password, textarea, file or select; at most 20 of them.
For "method": "oauth", add an auth.oauth block with authorizationUrl, tokenUrl and
scopes — that service’s scopes, not Tappify’s — plus fields named client_id and
client_secret. The owner registers your extension with their own provider, pastes those in, and
presses Connect on the extension’s page.
The provider sends the owner back to Tappify, not to you, so the owner has to register this
redirect URI with the provider:
redirect_uri_mismatch. Tappify shows the
address beside the Connect button on the install’s page, and on your OAuth client page in the
portal so you can put it in your own instructions. On staging the host is the staging API origin
rather than api.tappify.ai; the path is the same.
Health
Tappify callsGET /tappify/health every fifteen minutes and at every publish. Answer 200 within
three seconds. The last 90 days of those answers are the uptime number on your listing, and under
99.5 % the listing is flagged.