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