Get the brands report
/v1/reports/brandsCompares your brand with your tracked competitors. The report has 1 row for each brand in each group, with the brand's visibility and share of voice. It counts every brand by the same rules as the comparison charts in the dashboard. Every brand in the report has a row in every group that has answers, with mentions: 0 when no answer named the brand.
visibility counts the answers that rank a brand or name it in the text. share_of_voice counts only the answers that rank it, and the shares of all brands in a group add up to 1. The competitor_id filter only chooses which rows to return after the numbers are calculated, so it does not change share_of_voice.
Authorization
apiKey An API key that you create in the Lumirank dashboard, on the Settings > API keys page. Send it in the Authorization header: Bearer lr_....
In: header
Query Parameters
The first day of the date range, as a UTC date in the format YYYY-MM-DD. The range includes this day. The default is 29 days before end_date, so the default range is 30 days.
dateThe last day of the date range, as a UTC date in the format YYYY-MM-DD. The range includes this day. The default is today. The range can be at most 90 days long.
dateHow to split the report into rows. Send up to 3 of these, separated by commas: day, week, or month (only 1 of these 3), engine, country, and prompt. The report has 1 row for each group of answers that have the same values, for example 1 row for each week and engine. Without it, the report has 1 row for each brand, for the whole date range.
The engines to include, separated by commas: chatgpt, gemini, perplexity, ai_mode, copilot, google_ai_overview, claude. Without it, every engine is included.
The countries to include, separated by commas, as 2-letter ISO 3166-1 country codes in capital or small letters. Without it, every country is included.
The ids of the prompts to include, separated by commas. Without it, every prompt that is not archived is included. The id of an archived prompt gets status 400 unless you send include_archived=true.
The intents of the prompts to include, separated by commas: brand, comparison, how_to, informational, other. The intent of a prompt is what its question asks for. Intent is only a filter: you cannot use it as a dimension.
The brands to return, separated by commas: ids from /v1/competitors, or the competitor_id from /v1/brand for your own brand. The numbers are calculated over all brands first, so this filter does not change share_of_voice.
Send true to include the answers of archived prompts. The default is false: they are left out, as in the dashboard.
falseHow to sort the rows. Send up to 3 columns, separated by commas. Add :asc after a column for the smallest values first, or :desc for the largest first. Without either, the order is asc. You can sort by any column that the report returns. The default order is by the time dimension if you ask for one, then by share_of_voice, largest first.
The number of rows on each page, from 1 to 10000. The default is 1000.
int32The number of rows to skip before this page starts, from 0 to 100000. The default is 0.
int32Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/reports/brands?start_date=2026-09-01&end_date=2026-09-30&dimensions=week&engine=chatgpt%2Cperplexity&country=US&prompt_id=a41e7c52-3d6b-4f0a-9c8e-1b2d3e4f5a60&intent=comparison&competitor_id=5e0b3f71-9a2c-4d8e-b6f4-2c1d0e9f8a73%2Cc77d2e91-5b4a-4f3c-8d2e-7a6b5c4d3e21&include_archived=true&order_by=share_of_voice%3Adesc&limit=1000&offset=0"by engine
{ "data": [ { "engine": "chatgpt", "competitor_id": "5e0b3f71-9a2c-4d8e-b6f4-2c1d0e9f8a73", "competitor_name": "Acme", "is_self": true, "answers": 412, "mentions": 173, "visibility": 0.4199, "ranked": 160, "share_of_voice": 0.2871, "visibility_index": 0.3012, "average_position": 2.4, "best_position": 1, "sentiment": 38.5 }, { "engine": "chatgpt", "competitor_id": "c77d2e91-5b4a-4f3c-8d2e-7a6b5c4d3e21", "competitor_name": "Globex", "is_self": false, "answers": 412, "mentions": 220, "visibility": 0.534, "ranked": 205, "share_of_voice": 0.3679, "visibility_index": 0.4123, "average_position": 1.9, "best_position": 1, "sentiment": 22 } ], "meta": { "report": "brands", "start_date": "2026-09-01", "end_date": "2026-09-30", "dimensions": [ "engine" ], "include_archived": false, "order_by": [ "share_of_voice:desc" ], "limit": 1000, "offset": 0, "total": 12, "has_more": false, "data_through": "2026-09-30T06:41:12Z" }}List mentions GET
Returns 1 row for each brand that a complete answer ranks or names, oldest answer first. Inside an answer, the ranked brands come first. A brand that the answer names only in its text has `position: null`. Your own brand has rows too, with `is_self: true`. To get the rows of 1 brand, send its `competitor_id`. For example, the id of Globex returns every answer that ranks or names Globex.
Get the citations report GET
Shows the websites and pages that AI engines cite for your prompts. The report has 1 row for each cited domain, or 1 row for each cited page with the `url` dimension. The counts are the same as in the domain and URL tables on the Citations page of the dashboard. If `dimensions` has neither `domain` nor `url`, the report adds `domain`. So `dimensions=week` returns 1 row for each week and domain. In each group, the `citation_share` of all rows adds up to 1. `citation_rate` divides by the `answers` that the visibility report gives for the same group. The citations in the answers of archived prompts are left out unless you send `include_archived=true`. This applies to the citations and to the answers that `citation_rate` divides by.