Periods
One frozen calendar month or quarter with every metric, its prior value, delta and direction, plus the metric registry that defines each figure.
Code example
curl -X GET 'https://api.trakkr.ai/get-period-summary?brand_id=00000000-0000-4000-8000-81f286d10c3c&period=2026-08&view=summary&compare=true&months=12' \
-H "Authorization: Bearer $TRAKKR_API_KEY"{
"brand": {},
"period": {
"key": "Synthetic sample",
"kind": "Synthetic sample",
"label": "Synthetic sample",
"start": "Synthetic sample",
"end": "Synthetic sample",
"status": "Synthetic sample",
"source": "Synthetic sample",
"restatements": [],
"coverage": {},
"fields_computed": [],
"fields_missing": [],
"notes": []
},
"metrics": {},
"breakdowns": {},
"headline_metric_ids": [],
"groups": [],
"metric_meta": {}
}Synthetic example. Values are made up.
API key required
60 req/minWhy periods
The dashboard headline is a single day's report, and a days window recomputes over a rolling window that answers differently on the 3rd and the 9th. That drift is what puts an inverted arrow in a month-over-month deck. A period is a scoping parameter, not a date filter: period=2026-08 names the row frozen when August closed, and it answers identically however later it is asked.
A closed month is frozen on the 1st and read from the archive. The open month is computed month to date and says so (status: open). A quarter is derived from its three months by a rule per metric: averages weighted by measured days or runs, counts summed, end-of-period figures taken from the last archived month. A recompute that changes a stored figure is recorded as a restatement rather than silently overwriting it. The same resolver serves the API, the MCP server, the Agent and the Reports page, so a number cannot differ between them for the same period.
Endpoint
/get-period-summaryAuthenticate with Authorization: Bearer $TRAKKR_API_KEY. Key and access guide
Request parameters
brand_idstring | nullqueryOptional
Brand UUID. Required unless brand_ids is given; never both.
Format: uuid
brand_idsstring[] | nullqueryOptional
Several brands at once: brand UUIDs, comma-separated or repeated, up to 12 after de-duplication, instead of brand_id. Returns one compact row per brand per closed month with the prior month's delta already computed; view, compare and include do not apply. period as YYYY-MM keeps that month and the month before it; quarters are not available for a brand list yet. months caps how many closed months are returned (at most 12). Ids that are not among your brands are listed in excluded and never read.
periodstring | nullqueryOptional
A month as YYYY-MM or a quarter as YYYY-Qn. Defaults to the most recently closed month. With brand_ids, a month keeps that month and the month before it; quarters are not available for a brand list yet.
viewstringqueryOptional
summary (default), or list: the index of archived months and quarters
Default: "summary" · Options: "summary", "list"
comparebooleanqueryOptional
Include the prior period and the computed deltas
Default: true
includestring | nullqueryOptional
Comma-separated extras. 'definitions' adds each metric's one-line definition.
monthsintegerqueryOptional
view=list: how many closed months to index. With brand_ids: how many closed months to return per brand, at most 12.
Default: 12 · Minimum: 1 · Maximum: 36
Responses and errors
200Successful Response
application/json
PeriodSummaryResponse
brandobjectRequired
periodobjectRequired
What a period-scoped response actually resolved.
Fields in period
keystringRequired
kindstringRequired
labelstringRequired
startstringRequired
endstringRequired
statusstringRequired
sourcestringRequired
frozen_atstring | nullOptional
pipeline_versionstring | nullOptional
restated_atstring | nullOptional
restatementsobject[]Optional
Default: []
Fields in restatements
Array of object. Default: []
object. Additional keys are allowed.
coverageobjectOptional
Default: {}
fields_computedstring[]Optional
Default: []
Fields in fields_computed
Array of string. Default: []
string.
fields_missingstring[]Optional
Default: []
Fields in fields_missing
Array of string. Default: []
string.
notesstring[]Optional
Default: []
Fields in notes
Array of string. Default: []
string.
monthsobject | nullOptional
rank_sourcestring | nullOptional
priorobject | nullOptional
Fields in prior
PeriodMeta
keystringRequired
kindstringRequired
labelstringRequired
startstringRequired
endstringRequired
statusstringRequired
sourcestringRequired
frozen_atstring | nullOptional
pipeline_versionstring | nullOptional
restated_atstring | nullOptional
restatementsobject[]Optional
Default: []
Fields in restatements
Array of object. Default: []
object. Additional keys are allowed.
coverageobjectOptional
Default: {}
fields_computedstring[]Optional
Default: []
Fields in fields_computed
Array of string. Default: []
string.
fields_missingstring[]Optional
Default: []
Fields in fields_missing
Array of string. Default: []
string.
notesstring[]Optional
Default: []
Fields in notes
Array of string. Default: []
string.
monthsobject | nullOptional
rank_sourcestring | nullOptional
null
null.
metricsobjectRequired
breakdownsobjectOptional
Default: {}
headline_metric_idsstring[]Optional
Default: []
Fields in headline_metric_ids
Array of string. Default: []
string.
groupsobject[]Optional
Default: []
Fields in groups
Array of object. Default: []
object. Additional keys are allowed.
metric_metaobjectOptional
Default: {}
definitionsobject | nullOptional
PeriodIndexResponse
brandobjectRequired
periodsobject[]Required
Fields in periods
Array of object.
keystringRequired
kindstringRequired
labelstringRequired
statusstringRequired
sourcestringRequired
startstring | nullOptional
endstring | nullOptional
data_statusstring | nullOptional
frozen_atstring | nullOptional
restated_atstring | nullOptional
complete_report_setboolean | nullOptional
months_archivedinteger | nullOptional
days_elapsedinteger | nullOptional
quartersobject[]Optional
Default: []
Fields in quarters
Array of object. Default: []
keystringRequired
kindstringRequired
labelstringRequired
statusstringRequired
sourcestringRequired
startstring | nullOptional
endstring | nullOptional
data_statusstring | nullOptional
frozen_atstring | nullOptional
restated_atstring | nullOptional
complete_report_setboolean | nullOptional
months_archivedinteger | nullOptional
days_elapsedinteger | nullOptional
currentobjectRequired
Fields in current
keystringRequired
kindstringRequired
labelstringRequired
statusstringRequired
sourcestringRequired
startstring | nullOptional
endstring | nullOptional
data_statusstring | nullOptional
frozen_atstring | nullOptional
restated_atstring | nullOptional
complete_report_setboolean | nullOptional
months_archivedinteger | nullOptional
days_elapsedinteger | nullOptional
PeriodPortfolioResponse
monthsobject[]Required
Fields in months
Array of object.
keystringRequired
labelstringRequired
startstringRequired
endstringRequired
brandsobject[]Required
Fields in brands
Array of object.
idstringRequired
namestring | nullOptional
websitestring | nullOptional
domainstring | nullOptional
notesstring[]Optional
Default: []
Fields in notes
Array of string. Default: []
string.
rowsobject[]Required
Fields in rows
Array of object.
brand_idstringRequired
periodstringRequired
labelstringRequired
startstringRequired
endstringRequired
statusstringRequired
sourcestringRequired
data_statusstring | nullOptional
frozen_atstring | nullOptional
restatedbooleanOptional
Default: false
report_daysinteger | nullOptional
metricsobjectOptional
Default: {}
notestring | nullOptional
metric_idsstring[]Required
Fields in metric_ids
Array of string.
string.
metric_metaobjectOptional
Default: {}
currentobjectRequired
notesstring[]Optional
Default: []
Fields in notes
Array of string. Default: []
string.
excludedobject[]Optional
Default: []
Fields in excluded
Array of object. Default: []
brand_idstringRequired
reasonstringRequired
401Missing, malformed, or expired credentials
application/json
detailstring | object | nullOptional
errorstring | nullOptional
402The current plan does not fund this operation
application/json
detailstring | object | nullOptional
errorstring | nullOptional
403Invalid credentials, missing brand access, or insufficient role
application/json
detailstring | object | nullOptional
errorstring | nullOptional
422Validation Error
application/json
detailobject[]Optional
Fields in detail
Array of object.
locstring | integer[]Required
Fields in loc
Array of string | integer.
string
string.
integer
integer.
msgstringRequired
typestringRequired
429Rate limit exceeded
application/json
detailstring | object | nullOptional
errorstring | nullOptional
500The operation failed
application/json
detailstring | object | nullOptional
errorstring | nullOptional
503Authentication, entitlement, or a required dependency is temporarily unavailable
application/json
detailstring | object | nullOptional
errorstring | nullOptional
Returns the whole month or quarter: every single-number metric under metrics with the prior period alongside and the delta and direction already computed, the lists and maps under breakdowns, and the unit and direction of each metric under metric_meta.
Try GET /get-period-summary
view=summary (default)
Without period the summary is for the most recently closed month. The period block says exactly what was resolved; read status and source before publishing a figure.
curl -X GET 'https://api.trakkr.ai/get-period-summary?brand_id=00000000-0000-4000-8000-81f286d10c3c&period=2026-08&view=summary&compare=true&months=12' \
-H "Authorization: Bearer $TRAKKR_API_KEY"{
"brand": {},
"period": {
"key": "Synthetic sample",
"kind": "Synthetic sample",
"label": "Synthetic sample",
"start": "Synthetic sample",
"end": "Synthetic sample",
"status": "Synthetic sample",
"source": "Synthetic sample",
"restatements": [],
"coverage": {},
"fields_computed": [],
"fields_missing": [],
"notes": []
},
"metrics": {},
"breakdowns": {},
"headline_metric_ids": [],
"groups": [],
"metric_meta": {}
}Synthetic example. Values are made up.
delta, a positions_gained of 1 and a direction of up. Print the direction word, not the sign of the delta.Breakdowns
Lists and maps live under breakdowns, each with the prior period alongside where it exists.
model_visibility:models[]with visibility, presence, measured days and mentions per model, plusstrongest,weakestandzero_modelstop_competitors:competitors[]with rank, visibility,prior_rank,positions_gained,visibility_deltaandnew_in_list, plusnotable_change, the rival that gained mosttop_prompts: the prompts with the highest average visibility, each flaggednew_entrantagainst the prior periodtag_visibility: average visibility per prompt tag withzero_promptsand the prior valueperception_categories:categorieskeyed by category with score, prior and direction, plusstrongestandweakestperception_competitors: average perception score per tracked competitor, the brand includeddescriptors_end:primary,emergingandfadingdescriptors from the last perception run of the periodcitation_top_pages: the pages naming the brand that were cited most, with citations inside the period and the models that cited themcitation_top_gap_domains: the domains cited most with no page naming the brand, the outreach targets
view=list
The archive index: which closed months exist for the brand, the quarters they form, and the open month. Use it before asking for a period so a missing month is not mistaken for a month with no data.
curl -X GET 'https://api.trakkr.ai/get-period-summary?brand_id=00000000-0000-4000-8000-81f286d10c3c&view=list&compare=true&months=12' \
-H "Authorization: Bearer $TRAKKR_API_KEY"{
"brand": { "id": "00000000-0000-4000-8000-81f286d10c3c", "name": "Notion", "website": "https://notion.so" },
"periods": [
{
"key": "2026-08",
"kind": "month",
"label": "August 2026",
"start": "2026-08-01",
"end": "2026-08-31",
"status": "closed",
"source": "archive",
"data_status": "complete",
"frozen_at": "2026-09-01T03:12:44+00:00",
"restated_at": null,
"complete_report_set": true
},
{
"key": "2026-07",
"kind": "month",
"label": "July 2026",
"start": "2026-07-01",
"end": "2026-07-31",
"status": "closed",
"source": "archive",
"data_status": "complete",
"frozen_at": "2026-08-01T03:10:02+00:00",
"restated_at": "2026-08-14T09:30:11+00:00",
"complete_report_set": true
}
],
"quarters": [
{ "key": "2026-Q3", "kind": "quarter", "label": "Q3 2026", "start": "2026-07-01", "end": "2026-09-30", "status": "open", "source": "derived_from_months", "months_archived": 2 }
],
"current": { "key": "2026-09", "kind": "month", "label": "September 2026", "status": "open", "source": "computed", "days_elapsed": 11 }
}Synthetic example. Values are made up.
Status, sources and restatements
status is closed or open. An open month is month to date, is never persisted, carries no month-end rank, and will change until it closes. A quarter with a month still running is open too.
source says where the figures came from. archive is the frozen row. computed is the open month, or a closed month that was not archived yet and has just been computed from retained raw data and stored; it is frozen from then on, and one request fills at most one month. derived_from_months is a quarter. missing means the archive holds nothing for that brand and month and the fill was not possible in this request; every metric is null and notes says so.
A recompute that changes a stored figure appends an entry to restatements with at, note, the pipeline version before and after, and changed keyed by field with the old and new value. The original frozen_at is kept and restated_at marks the latest restatement, so a report can name the change instead of showing a different number with no explanation.
value: null, its breakdown is dropped, and period.notes names the withheld groups.Get Metrics
/get-metricsAuthenticate with Authorization: Bearer $TRAKKR_API_KEY. Key and access guide
Responses and errors
200Successful Response
application/json
groupsobject[]Required
Fields in groups
Array of object.
object. Additional keys are allowed.
metricsobjectRequired
comparison_kindsstring[]Required
Fields in comparison_kinds
Array of string.
string.
401Missing, malformed, or expired credentials
application/json
detailstring | object | nullOptional
errorstring | nullOptional
402The current plan does not fund this operation
application/json
detailstring | object | nullOptional
errorstring | nullOptional
403Invalid credentials, missing brand access, or insufficient role
application/json
detailstring | object | nullOptional
errorstring | nullOptional
429Rate limit exceeded
application/json
detailstring | object | nullOptional
errorstring | nullOptional
500The operation failed
application/json
detailstring | object | nullOptional
errorstring | nullOptional
503Authentication, entitlement, or a required dependency is temporarily unavailable
application/json
detailstring | object | nullOptional
errorstring | nullOptional
The metric registry: every figure the period endpoints report, with its label, one-line definition, unit, direction of improvement, how a month is formed from daily readings, and how two periods compare. It takes no brand_id. Product tooltips, the Learn metrics page and the MCP trakkr://metrics resource render from the same source.
curl -X GET 'https://api.trakkr.ai/get-metrics' \
-H "Authorization: Bearer $TRAKKR_API_KEY"{
"groups": [
{
"id": "visibility",
"label": "Visibility",
"tagline": "How often and how prominently the brand shows up in AI answers.",
"metrics": [
{
"id": "visibility_avg",
"label": "Visibility average",
"group": "visibility",
"unit": "score",
"precision": 1,
"better": "higher",
"aggregation": "mean_daily",
"comparison": "points",
"kind": "measure",
"definition": "How prominently AI models mention the brand across every tracked prompt and model, weighted by where it appears in the answer, averaged over each measured day in the period. 0 to 100.",
"aggregation_note": "Average of the daily values inside the period, one value per day.",
"quarter_rule": "weighted_days",
"learn_url": "https://trakkr.ai/learn/metrics#visibility"
}
]
}
],
"metrics": {
"visibility_avg": { "...": "the same entry, keyed by id" }
},
"comparison_kinds": ["points", "percent", "positions", "none"]
}Synthetic example. Values are made up.
The 35 metric ids, in the order a report reads them. Visibility: visibility_avg, presence_avg, mentions_total, position_avg (answer position when mentioned, not competitor rank), visibility_min, visibility_max, report_days, model_visibility. Competitors: rank_end, rank_avg, rank_pool_end, top_competitors. Citations: citations_total, citation_brand_mentions, citation_brand_pages_cumulative_end, citation_days, citation_source_domains_end, citation_source_domains_brand_end, citation_source_domain_share_pct, citation_top_pages, citation_top_gap_domains. Prompts: prompts_measured, prompts_with_visibility, prompt_coverage_pct, top_prompts, tag_visibility. Perception: perception_score_avg, perception_categories, perception_competitors, descriptors_end, perception_runs. Site health: audit_score_end, audit_open_issues_end, audit_count. Traffic: ai_sessions_total, AI-referred sessions from the connected analytics property, read once, three days after the month ends, so the provider has finished counting it.
The definitions in prose are on the Learn metrics page.
period on the other endpoints
Seven read endpoints accept period=YYYY-MM or period=YYYY-Qn and then read their own shape from the archive. When period is set, days is ignored and the response carries the same period block as above. A malformed key returns 400.
/get-scores: every view. Not combinable withtag_idsorprompt_id(400); visibility by tag for the period is in the summary's breakdowns./get-rankings:view=overallonly.win_rateandthreat_countare null, and a month with no archived rank returns 404./get-models:total_queriesis the number of measured days for the model,presenceis filled, and theaverage_positionand top-3 fields are null./get-competitor-data:view=summaryonly, and the response takes a period shape:your_rank,rank_pool,your_visibility,competitors[]withprior_rank,positions_gained,visibility_deltaandnew_in_list,notable_changeandperception_competitors./get-citations:view=top_pagesandview=analytics.appearance_countis the page's citations inside the period, withappearance_count_periodandmodelsalongside. In analytics,top_domainsare the domains cited most with no page naming the brand, andperiod_figurescarries the brand-page figures./get-perception:view=dashboardandview=metrics.perception_score.change_periodis the change against the prior period./get-audits: the audit whose score stood at the end of the period. Site health for the period isaudit_score_endin the summary.
Use Cases
- Build a monthly client report that fetches the same figures again next quarter
- Compare August with July, or Q3 with Q2, with the direction already right for ranks
- Check
status,sourceandrestatementsbefore a number goes into a deck - Render metric labels, units and definitions from
/get-metricsinstead of hard-coding them - List what is archived with
view=listbefore backfilling a warehouse
