GET /api/v1/process/status/
Returns a Server-Sent Events stream with progress updates and the final analysis result.
Request
http
GET /api/v1/process/status/{task_id}
Authorization: Bearer YOUR_KEY
Accept: text/event-streamEvent Types
Each event is a JSON object on a data: {...} line.
PROGRESS
json
{
"state": "PROGRESS",
"progress": 45,
"details": {
"step": "analysis_internal",
"message": "Computing TF-IDF vectors"
}
}SUCCESS
json
{
"state": "SUCCESS",
"progress": 100,
"result": {
"Umbrella Analysis": [...],
"Block Comparison": [...],
"N-grams Analysis": [...],
"Anchors Analysis": [...],
"Triplets Analysis": {...}
}
}FAILURE
json
{
"state": "FAILURE",
"error": { "code": 1001, "message": "Failed to parse page: timeout" }
}Result Structure
| Key | Always | Description |
|---|---|---|
"Umbrella Analysis" | ✅ | Semantic proximity gaps — words to add |
"Block Comparison" | ✅ | TF-IDF word density comparison |
"N-grams Analysis" | ✅ | 2–3 word phrase patterns |
"Anchors Analysis" | ✅ | Anchor texts with href URLs |
"Triplets Analysis" | ⚡ extended | Knowledge Graph (only with triplet_analysis: true) |
"Umbrella Analysis" item
json
{
"lemma": "warranty",
"competitor_avg_score": 1.84,
"own_score": 0.0,
"gap": 1.84,
"coverage_percent": 75.0,
"recommendation": "Add to H2/H3",
"context_snippet": "12-month warranty included"
}"Block Comparison" item
json
{
"word": "mattress",
"lemma": "mattress",
"frequency": 8.3,
"frequency_own_page": 2,
"pct_target_comp_avg": -45.2,
"action_needed": "increase",
"present_on_own_page": true
}"N-grams Analysis" item
json
{
"ngram": "free shipping",
"ngram_type": "bigrams",
"pages_count": 4,
"frequency_avg": 2.5,
"present_on_own_page": false
}"Anchors Analysis" item
json
{
"anchor": "shop now",
"frequency_own": 0,
"frequency_comp_avg": 3.2,
"pages_count": 3,
"links": ["https://comp1.com/shop", "https://comp2.com/store"]
}"Triplets Analysis"
json
{
"entities": [
{
"subject": "Mattress",
"tier": "core",
"triplets_count": 12,
"sources_count": 4,
"triplets": [
{
"predicate": "filler material",
"object": "independent springs",
"sources": ["comp1.com", "comp2.com"]
}
]
}
],
"missing_triplets": {
"critical": [...],
"important": [...],
"unique": [...]
},
"stats": {
"total_triplets": 87,
"sources_with_content": 5,
"gaps_critical": 3,
"gaps_important": 8,
"gaps_unique": 21,
"gaps_total": 32
}
}Python Example
python
import requests, json
BASE = "https://unihra.ru/api/v1"
HEADERS = {"Authorization": "Bearer YOUR_KEY"}
with requests.get(
f"{BASE}/process/status/{task_id}", headers=HEADERS, stream=True
) as resp:
for line in resp.iter_lines():
if not line or not line.startswith(b"data: "):
continue
event = json.loads(line[6:])
state = event["state"]
if state == "PROGRESS":
print(f"[{event['progress']}%] {event.get('details', {}).get('message', '')}")
elif state == "SUCCESS":
result = event["result"]
gaps = result.get("Umbrella Analysis", [])
for g in gaps[:5]:
print(f"{g['lemma']:20s} gap={g['gap']:.2f} → {g['recommendation']}")
break
elif state == "FAILURE":
err = event.get("error", {})
raise RuntimeError(f"[{err.get('code')}] {err.get('message')}")