LoudminkLoudmink
REST API

Reports and Insights

Download progress reports and source exports, with exact filters, limits and access requirements.

All endpoints on this page accept the workspace key. There are two different report downloads: a rolling progress PDF and a filtered Insights PDF/CSV. Neither schedules future delivery.

GET /api/report/export

Download the manager-facing AI visibility report as PDF.

Query parameterAccepted value / default
days30 or 90; numeric conversion is used, other values fall back to 30
compareComparison is on by default; only false turns it off
curl --fail-with-body 'https://loudmink.ai/api/report/export?days=30&compare=true' \
  -H "Authorization: Bearer $LOUDMINK_API_KEY" \
  --output visibility-report.pdf

This is a rolling 30- or 90-day report, not a selected calendar month's report. It combines visibility trends, competitors, source control, recorded work and next steps. Comparisons use the immediately preceding equal-length period; insufficient history or a substantially changed question set can suppress comparison language. With compare=false, it shows current standing.

The report uses plan-allowed engines. This download does not require a separate active subscription check. Simulated demonstration results cannot be exported (403). If the report has no tracked questions, it returns 409 with Add buyer questions to monitor before exporting a report. Generation errors return 500.

Side effects: if Google Search Console is connected at organisation level with a selected property, the report may contact Google. Token handling can update credentials or remove a revoked integration. This is not a strictly database-read-only request. Search data failures degrade to AI-only metrics. The source split uses up to 2,000 most-cited distinct URLs per window; this PDF is not an exhaustive raw-data export.

Success is binary application/pdf, with an attachment filename and Cache-Control: private, no-store.

POST /api/insights/report

Download a filtered Insights report (pdf) or source rows (csv). Requires active workspace access. JSON body:

FieldType / rule
productIdRequired string, 1–100 characters; must equal the key's workspace ID
cycleIdOptional string, 1–100 characters; selects a completed saved campaign report from this workspace; PDF only
summaryRangeString "30" or "90"; default "30"
rangeByCategoryOptional object mapping category keys to "30" or "90"; omitted entries always default to "30", independently of summaryRange
engineFilterByCategoryOptional object mapping category keys to all, chatgpt, claude, grok, gemini or perplexity; default all
timeZoneOptional string, 1–64 characters; display formatting only; unknown zones fall back to UTC
formatpdf (default) or csv

Category keys: community, video, social_visual, social_pro, editorial, news, directory, reference, company. Data is restricted to plan-allowed categories and engines. An explicitly requested engine unavailable on the plan is rejected with 403. Community child-thread totals remain all-engine totals even when their parent group is filtered to one engine.

Replace workspace-id with the ID for the same workspace as the key (for example, the productId returned by content-plan GET). Unknown body properties are rejected. Numeric 30 is not the same as the required string "30".

curl --fail-with-body 'https://loudmink.ai/api/insights/report' \
  -H "Authorization: Bearer $LOUDMINK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"productId":"workspace-id","summaryRange":"30","format":"pdf"}' \
  --output insights.pdf

For source data, change format to csv and the output filename to insights.csv. Without cycleId, the PDF can include the latest completed saved campaign narrative as well as current source sections. With cycleId, it exports that saved narrative without loading the source breakdown. CSV exports source rows, not the narrative, and cannot be combined with cycleId.

CSV columns: section, category, source title, url, citations, engines, workspace queries checked, source influence (sites only), control. The file is UTF-8 with a BOM, CSV escaping and spreadsheet-formula protection. Site overview rows and detailed source rows represent different levels; do not sum every row into a single citation total.

Export limits and responses

  • 10 attempts reaching the export limiter per key/workspace every 10 minutes. Requests rejected before that check do not consume it; later validation failures can. Handle 429 responses before retrying.
  • Body text is limited to 8,000 characters. Malformed JSON, unknown fields or invalid filters return 400.
  • Mismatched workspace, unavailable engine or access refusal: 403. Missing workspace or requested saved report: 404.
  • More than 50,000 URL/engine tuples, 200,000 URL/engine/query combinations in a source window, or 100,000 characters of saved narrative plus diff: 413, with guidance to narrow the export.
  • PDF detail is capped at 100 rows per section, with a cap note. CSV removes those per-section row caps, but retains the source-read limits and plan restrictions. The Key sources overview remains the top 10 sites.
  • Rate limit: 429. Unexpected export failure: 500.

Success returns an attachment with application/pdf or text/csv; charset=utf-8, plus Cache-Control: private, no-store and X-Content-Type-Options: nosniff. No uniform Retry-After header is supplied by this handler.

The export uses fresh source reads, does not run domain classification or write AI credits, and does not create a new AI-generated narrative. Authentication can still update the key's last-used timestamp.

GET /api/insights/sources

Read the source breakdown used by the Insights screen. Requires active workspace access.

days=90 selects 90; any other value, including omission, selects 30. There is no pagination. The response is a direct object, not wrapped in data:

{
  days: 30 | 90,
  since: string, // YYYY-MM-DD cutoff
  summary: { total, self, competitor, thirdParty, unclassified, workable },
  keySources: [{
    key, url, label, channel, category, impact, citations,
    isSelf, isCompetitor, isWorkable,
    children: [{ url, label, counts, total, category }]
  }],
  categories: [{ key, totalCitations, items }]
}

This is a field sketch, not a literal JSON example. Summary fields and citation totals are numbers. counts contains numeric counts for perplexity, chatgpt, grok, gemini, claude. A category item is either a leaf (key, url, label, counts, total, isCompetitor, isSelf) or a group (same fields without url, plus children containing url, label, counts, total). Its kind distinguishes the two. impact is a rounded market-weighted answer-coverage percentage, or null without a measurable query surface.

Bounds: heavy reads can be cached for 30 minutes. Input reads cap at 5,000 URL/engine tuples and 60,000 URL/engine/query cells. Results include at most 10 key sites, 50 children per key site, 50 items per category and 25 children per group. Category totals sum returned items; the summary and category rows need not reconcile because of caps and plan filtering. Use the export above for broader source detail.

Side effects: may classify source domains using AI and persist classifications (up to 150 candidate domains per request). It is not a no-cost, read-only endpoint merely because it uses GET. Unexpected errors return 500 with Failed to compute source breakdown.

GET /api/insights/competitor-network

Read citation sources grouped by channel for a competitor or your own brand.

Query parameterMeaning
daysExact 90 selects 90; otherwise 30
selfExact 1 selects your brand using the workspace's website domain
domainCompetitor domain; normalised to a registrable domain
nameCompetitor name; usable when no domain is supplied

Supply self=1, or a competitor domain/name. Missing both returns 400. Self mode without a workspace website domain also returns 400.

Success returns { days, competitor, totalCitations, channels }. competitor has name, domain, faviconUrl, isSelf. Each channel has key, label, total, sources; each source has url, label, site, faviconUrl, type (self or third-party), count. Channels and their sources are ranked by count. No matches produce an empty list and zero total, not 404.

This saved-data endpoint has no additional active-subscription requirement and does not use pagination. It reads stored digests/citations and existing classification data rather than generating a fresh competitor analysis. Unexpected failures return 500 with Failed to compute competitor network.

Free visibility report

Not sure if AI search engines recommend you?

Get a free report showing who they recommend instead of you, where they get their answers, and what you can fix.