--- title: "Historia fraz: utracone (`getLost`)" source: https://docs.senuto.com/modules/visibility_analysis/va-history-keywords-getLost api: POST /api/visibility_analysis/reports/history/keywords/getLost --- # Historia fraz: utracone (`getLost`) **`POST /api/visibility_analysis/reports/history/keywords/getLost`** Zwraca frazy **utracone** w zadanym zakresie dat: na `date_min` domena rankowała w TOP50, a na `date_max` już nie rankuje (tryb `MODE_LOSE` tego samego komponentu danych co `getData`). W zwracanych wierszach `statistics.position.current` ma zawsze wartość sentinela `51` (poza TOP50), `statistics.url.current` jest puste, `statistics.url.is_change` = `1`, a `statistics.visibility` ma `current`, `diff` i `percent` równe `0`. Struktura żądania jest identyczna jak w `getData`. > **Ostrzeżenie:** > **Tych wierszy nie ma w [`getLosses`](/modules/visibility_analysis/va-history-keywords-getLosses).** Mimo że fraza utracona formalnie „spadła", jest z tamtej akcji wykluczona — `getLosses` pokazuje wyłącznie ruch wewnątrz TOP50. Zbiory są rozłączne, więc **pełny obraz strat uzyskasz, sklejając `getLosses` + `getLost`**, bez ryzyka duplikatów. > > Uwaga: w drugą stronę jest inaczej. [`getAcquired`](/modules/visibility_analysis/va-history-keywords-getAcquired) jest podzbiorem [`getWins`](/modules/visibility_analysis/va-history-keywords-getWins) i tam sklejenie zdubluje wiersze. Ta asymetria może się w przyszłości ujednolicić. | Fraza | ID frazy | KID | Domena | Liczba słów | Pozycja | Pozycja poprz. | Zmiana pozycji | Wzrosty | Spadki | Bez zmian | Widoczność | Widoczność poprz. | Δ widoczności | Widoczność % | URL bieżący | URL poprzedni | URL zmiana | CPC | Wyszukiwania/mies. | Trend (12 mies.) | Szczyt trendu | Trudność | Snippety SERP | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | borussia moenchengladbach logo | 11657796 | 9e1033c838a972be0305152154779f8b | zalando.pl | 3 | 51 | 31 | 20 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | zalando.pl/puma-borussia-moenchengladbach-auswaert-t-shirt-z-nadrukiem-green-warm-white-pu126g03c-m11.html | 1 | 0 | 10 | [10,10,10,10,10,0,10,10,10,10,10,10] | | 27 | ["ai_overview","image_thumbs","people_also_ask","spell"] | | anglomania facebook | 11647848 | 9dedff1fff760c052111f045eb9fba0c | zalando.pl | 2 | 51 | 30 | 21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | zalando.pl/vivienne-westwood-anglomania-sweter-blue-zir02g5tv-001.html | 1 | 0 | 10 | [0,10,0,0,0,0,0,0,0,10,0,0] | | 29 | ["image_thumbs"] | _zalando.pl, sort: widoczność malejąco — frazy utracone w zakresie. Bieżąca pozycja `51` to sentinel „poza TOP50”, a poprzedni URL pochodzi z ostatniej daty, na którą domena rankowała. Wszystkie pola wiersza (poza mapą historii `statistics.position.history`, która ma zmienne klucze-daty — jest w JSON i sekcji „Struktura odpowiedzi”)._ --- ## Żądanie `POST` `/api/visibility_analysis/reports/history/keywords/getLost` Nagłówki: `Authorization: Bearer `, `Content-Type: application/json`. ### Struktura żądania **Podstawowy** ```jsonc filename="żądanie-podstawowe.jsonc" { "domain": "zalando.pl", "fetch_mode": "topLevelDomain", "date_min": "2026-06-20", "date_max": "2026-06-29", "country_id": 1, "order": { "prop": "statistics.visibility.current", "dir": "desc" } } ``` **Rozszerzony** ```jsonc filename="żądanie-rozszerzone.jsonc" { "domain": "zalando.pl", "fetch_mode": "topLevelDomain", "date_min": "2026-06-20", "date_max": "2026-06-29", "country_id": 1, "order": { "prop": "statistics.visibility.current", "dir": "desc" }, "limit": 2, "page": 1 } ``` **cURL** ```bash curl --location --request POST 'https://api.senuto.com/api/visibility_analysis/reports/history/keywords/getLost' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer $YOUR_TOKEN_HERE' \ --data-raw '{ "domain": "zalando.pl", "fetch_mode": "topLevelDomain", "date_min": "2026-06-20", "date_max": "2026-06-29", "country_id": 1, "order": { "prop": "statistics.visibility.current", "dir": "desc" } }' ``` ### Parametry ```ts type HistoryKeywordsGetLostRequest = { /** * **Wymagane**. Domena, subdomena, katalog lub URL do analizy — interpretowane zgodnie z `fetch_mode`. */ domain: string; /** * **Wymagane**. Sposób interpretacji `domain`. * - `topLevelDomain` — cała domena (najczęstszy przypadek; wartość "domain" nie istnieje) * - `subdomain` — pojedyncza subdomena * - `catalog` — ścieżka/katalog * - `url` — dokładny URL */ fetch_mode: 'topLevelDomain' | 'subdomain' | 'catalog' | 'url'; /** * **Wymagane**. Początek zakresu dat, `YYYY-MM-DD`. Na tę datę domena rankowała w TOP50 na zwracane frazy. * Dostępne daty pobierzesz akcją `getDates`. */ date_min: string; /** * **Wymagane**. Koniec zakresu dat, `YYYY-MM-DD`. Na tę datę domena już **nie** rankuje na zwracane frazy. */ date_max: string; /** * **Wymagane**. Id kraju (bazy danych). Polska = `1`. Nieznana wartość → `418` "Unknown country_id". */ country_id: number; /** * **Wymagane**. **Pojedyncza** dyrektywa sortowania (jeden obiekt — nie tablica). * `prop` to jedna z dozwolonych właściwości sortowalnych; `dir` to kierunek. * * Dozwolone wartości `prop`: * - `keyword` * - `statistics.position.current` * - `statistics.position.previous` * - `statistics.position.diff` * - `statistics.visibility.current` * - `statistics.visibility.previous` * - `statistics.visibility.diff` * - `statistics.difficulty.current` * - `statistics.searches.current` * - `statistics.cpc.current` * - `statistics.url.is_change` * * Błędny `prop` → `418` `invalid_data` z komunikatem "This value is not allow. Please use correct colum name". */ order: { prop: | 'keyword' | 'statistics.position.current' | 'statistics.position.previous' | 'statistics.position.diff' | 'statistics.visibility.current' | 'statistics.visibility.previous' | 'statistics.visibility.diff' | 'statistics.difficulty.current' | 'statistics.searches.current' | 'statistics.cpc.current' | 'statistics.url.is_change'; dir: 'asc' | 'desc'; }; /** * Liczba wierszy na stronę. * @default 10 */ limit?: number; /** * Numer strony. * @default 1 */ page?: number; /** * Tablica grup filtrów — ten sam mechanizm i te same klucze co w `positions/getData` * oraz `history/keywords/getData`. Szczegóły: [typy filtrów](/types/filter). */ filtering?: FilterGroup[]; } export default HistoryKeywordsGetLostRequest ``` > **Ostrzeżenie:** > **`order` to pojedynczy obiekt** (`{ prop, dir }`) — nie tablica. Używaj ścieżek `prop` z kropkami wymienionych powyżej; inne wartości zwracają `418` z komunikatem `"This value is not allow. Please use correct colum name"`. > **Ostrzeżenie:** > Pięć parametrów jest **wymaganych**: **`domain`**, **`fetch_mode`**, **`date_min`**, **`date_max`** oraz **`country_id`**, a także pojedynczy obiekt **`order`** (`{ prop, dir }` — nie tablica). Wartość `fetch_mode` = `"domain"` **nie istnieje** — używaj `topLevelDomain`. Nieznane `country_id` zwraca `418` z komunikatem `"Unknown country_id"`. Pozycja `51` to sentinel oznaczający „poza TOP50" — nie rzeczywistą pozycję w SERP. ## Odpowiedź W przypadku powodzenia otrzymujesz `data` (tablicę wierszy z frazami utraconymi) oraz `pagination`. Charakterystyka trybu `MODE_LOSE`: `position.current` = `51` (sentinel „poza TOP50"), `url.current` = `""`, `url.is_change` = `1` (liczbowo), a `visibility.current`, `visibility.diff` i `visibility.percent` = `0`. **Skrócona** ```json filename="przykładowa-odpowiedź (skrócona)" { "success": true, "data": [ { "keyword_id": 11657796, "keyword": "borussia moenchengladbach logo", "statistics": { "position": { "current": 51, "previous": 31 }, "visibility": { "current": 0, "percent": 0 } /* … */ } } ], "pagination": { "page_count": 1527, "current_page": 1, "has_next_page": true, "has_prev_page": false, "count": 3054, "limit": 2 } } ``` **Pełna** ```json filename="przykładowa-odpowiedź (200)" { "success": true, "data": [ { "keyword_id": 11657796, "kid": "9e1033c838a972be0305152154779f8b", "domain": "zalando.pl", "keyword": "borussia moenchengladbach logo", "words_count": 3, "statistics": { "position": { "current": 51, "previous": 31, "diff": 20, "changes": { "wins": 0, "losses": 0, "no_changes": 0 }, "history": { "2026-06-21": { "position": 0, "has_serp": true } } }, "visibility": { "current": 0, "previous": 0, "diff": 0, "percent": 0, "history": null }, "url": { "current": "", "previous": "zalando.pl/puma-borussia-moenchengladbach-auswaert-t-shirt-z-nadrukiem-green-warm-white-pu126g03c-m11.html", "is_change": 1 }, "cpc": { "current": 0 }, "searches": { "current": 10 }, "trends": { "history": [10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10], "peak": null }, "difficulty": { "current": 27 }, "snippets": { "current": ["ai_overview", "image_thumbs", "people_also_ask", "spell"] } } }, { "keyword_id": 11647848, "kid": "9dedff1fff760c052111f045eb9fba0c", "domain": "zalando.pl", "keyword": "anglomania facebook", "words_count": 2, "statistics": { "position": { "current": 51, "previous": 30, "diff": 21, "changes": { "wins": 0, "losses": 0, "no_changes": 0 }, "history": { "2026-06-21": { "position": 0, "has_serp": true } } }, "visibility": { "current": 0, "previous": 0, "diff": 0, "percent": 0, "history": null }, "url": { "current": "", "previous": "zalando.pl/vivienne-westwood-anglomania-sweter-blue-zir02g5tv-001.html", "is_change": 1 }, "cpc": { "current": 0 }, "searches": { "current": 10 }, "trends": { "history": [0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0], "peak": null }, "difficulty": { "current": 29 }, "snippets": { "current": ["image_thumbs"] } } } ], "pagination": { "page_count": 1527, "current_page": 1, "has_next_page": true, "has_prev_page": false, "count": 3054, "limit": 2 } } ``` ### Struktura odpowiedzi ```ts type HistoryKeywordsGetLostResponse = { /** `true` przy powodzeniu; przy błędzie `false` i koperta z `error` */ success: boolean; /** Zwrócone wiersze z frazami utraconymi */ data: LostKeywordRow[]; /** Metadane paginacji */ pagination: { page_count: number; current_page: number; has_next_page: boolean; has_prev_page: boolean; count: number; limit: number; }; } type LostKeywordRow = { keyword_id: number; kid: string; domain: string; keyword: string; words_count: number; statistics: { /** `current` = 51 — sentinel "poza TOP50" (fraza utracona) */ position: { current: 51; previous: number; diff: number; changes: { wins: number; losses: number; no_changes: number }; history: Record }; /** `current`, `diff` i `percent` = 0 (fraza poza TOP50 nie ma widoczności) */ visibility: { current: 0; previous: number; diff: 0; percent: 0; history: null }; /** `current` puste, `is_change` = 1 (liczbowo 0/1) */ url: { current: ''; previous: string; is_change: 1 }; cpc: { current: number }; searches: { current: number }; trends: { history: number[]; peak: number | null }; difficulty: { current: number }; snippets: { current: string[] }; }; } export default HistoryKeywordsGetLostResponse ``` ## Błędy ```ts type ErrorResponse = { success: false; data: { error: { /** np. invalid_data */ type: string; message: string; /** pole -> reguła -> komunikat (dla invalid_data) */ params?: Record>; }; }; } export default ErrorResponse ``` > **Błąd:** > **`418`** zwracany jest dla błędów walidacji. Brak wymaganego pola → `invalid_data`; nieznane `country_id` → `"Unknown country_id"`; błędny `order.prop` → `"This value is not allow. Please use correct colum name"`. > > **Znany błąd — odwrócony komunikat.** Przy `date_min > date_max` komunikat reguły `DateRangeRules` brzmi `"date_max must be less or equal than date_min"` — treść jest odwrócona; należy go odczytywać jako niepowodzenie reguły zakresu dat, a nie jako dosłowną instrukcję. ## Powiązane akcje - [`getData`](/modules/visibility_analysis/va-history-keywords) — frazy w zakresie dat (`MODE_DATA`) - `getWins` / `getLosses` — frazy, które zyskały / straciły pozycje w danym zakresie (taka sama struktura żądania) - [`getAcquired`](/modules/visibility_analysis/va-history-keywords-getAcquired) — frazy nowo pozyskane w zakresie (taka sama struktura żądania) - `getLost` — frazy całkowicie utracone w zakresie (ta strona) - `getDates` — dostępne daty dla zakresu (POST, wymaga tylko `country_id`)