Skip to content

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-stream

Event 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": {...}
  },
  "page_status": {
    "parsed": [{"url": "https://example.com/page", "is_own_page": true}],
    "failed": [{"url": "https://competitor.example/page", "is_own_page": false}]
  }
}

FAILURE ​

json
{
  "state": "FAILURE",
  "error": { "code": 1001, "message": "The analysis could not be completed." }
}

Result Structure ​

KeyAlwaysDescription
"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"⚡ extendedKnowledge 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"]
}

page_status ​

page_status is returned next to result, not inside the analysis result. parsed lists pages included in the analysis. failed lists requested pages that were not included. These lists expose only the URL and page role.

json
{
  "parsed": [
    {"url": "https://example.com/page", "is_own_page": true}
  ],
  "failed": [
    {"url": "https://competitor.example/page", "is_own_page": false}
  ]
}

"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')}")