Digest
The workspace digest is a synthesized overview: what needs review, activity by competitor and surface, who's moving, top SEO opportunities, and coverage stats. It powers the dashboard Overview tab.
Get digest
GET /v1/workspaces/:id/digest?period=7d
| Query param | Values | Default |
|---|---|---|
period |
1d, 7d, 30d |
7d |
curl "https://api.competiflow.com/v1/workspaces/42/digest?period=7d" \
-H "Authorization: Bearer $COMPETIFLOW_API_KEY"
Response (200 OK):
{
"digest": {
"period": "7d",
"generated_at": "2026-07-14T12:00:00.000Z",
"generating": false,
"needs_review": {
"count": 3,
"max_severity": "high",
"items": [
{
"change_id": 901,
"competitor_id": 7,
"competitor": "Example Co",
"homepage_url": "https://example.com",
"logo_url": "https://…",
"monitor_type": "pricing",
"source_url": "https://example.com/pricing",
"summary": "Pro plan dropped from $99 to $79/mo",
"severity": "high",
"why_it_matters": "Mid-market buyers comparing tiers side by side will see a lower entry price.",
"category": "pricing",
"direction": "retreated",
"delta": { "added": 0, "removed": 0, "modified": 1 },
"review_status": "unreviewed",
"created_at": "2026-07-14T12:30:00.000Z"
}
]
},
"activity_map": {
"surfaces": ["homepage", "blog", "docs", "changelog", "pricing"],
"max_count": 4,
"competitors": [
{
"competitor_id": 7,
"name": "Example Co",
"homepage_url": "https://example.com",
"logo_url": "https://…",
"total": 4,
"cells": { "pricing": 2, "blog": 2 }
}
]
},
"whos_moving": [
{
"competitor_id": 7,
"name": "Example Co",
"change_count": 4,
"max_severity": "high",
"sparkline": [0, 1, 0, 2, 1]
}
],
"top_opportunities": [
{
"change_id": 902,
"competitor_id": 8,
"competitor": "Rival Inc",
"homepage_url": "https://rival.example",
"logo_url": "https://…",
"monitor_type": "blog",
"source_url": "https://rival.example/blog",
"why_it_matters": "Publish comparison content targeting the same keywords.",
"opportunity_score": 85,
"enrichment_summary": "boom supersonic (18100/mo), supersonic flight (3600/mo), python scraper (900/mo)",
"post_title": "Boom Supersonic Guide",
"post_url": "https://rival.example/blog/boom-supersonic",
"post_count": 2,
"keyword_count": 18,
"total_volume": 126000,
"median_difficulty": 42,
"top_keywords": [
{ "keyword": "boom supersonic", "search_volume": 18100 },
{ "keyword": "supersonic flight", "search_volume": 3600 },
{ "keyword": "python scraper", "search_volume": 900 }
]
}
],
"coverage": {
"competitors_count": 4,
"monitors_total": 18,
"monitors_healthy": 17,
"monitors_failing": 1,
"failing_monitor_ids": [105]
},
"consumption": {
"pending": 3,
"max_unreviewed_severity": "high",
"reviewed_in_period": 12
}
}
}
Activity map (Overview UI only)
activity_map is included in the digest payload for the dashboard Overview tab. It is not sent in email, Slack, or webhook digests.
| Field | Description |
|---|---|
surfaces |
Fixed row order: homepage, blog, docs, changelog, pricing |
max_count |
Highest cell count in the matrix (used for heat scaling in the UI) |
competitors |
Competitors with ≥1 change in the period, sorted by total descending |
competitors[].cells |
Map of surface → change count; zero cells are omitted |
Cell heat colors are a UI concern only. Like whos_moving, this section is cached and may lag live feed data until the digest regenerates.
Top opportunities (Overview UI)
Ranked blog/docs SEO gaps from seo_opportunity enrichments. Each row is one change with a positive opportunity_score.
| Field | Description |
|---|---|
change_id |
Opens the change detail (full keyword table) |
competitor, monitor_type, source_url |
Who published and where |
opportunity_score |
0–100 score (volume vs difficulty, relevance-weighted) |
enrichment_summary |
Legacy comma-separated top keywords (email digests prefer premium fields above; fall back to this) |
post_title, post_url |
Strongest new post in the change (highest keyword volume) |
post_count |
Number of new posts in the change |
keyword_count |
Unique keywords with search volume |
total_volume |
Sum of unique keyword monthly search volume |
median_difficulty |
Median keyword difficulty (0–100) across unique keywords with difficulty data |
top_keywords |
Top 3 keywords by opportunity score → { keyword, search_volume } |
When post_title / top_keywords are absent (legacy cached digests), the Overview UI falls back to enrichment_summary.
Cold cache
When generating is true, the digest is being built in the background. Retry after a few seconds.
MCP equivalent
The MCP tool get_digest wraps this endpoint. See MCP server.