--- title: "Historia fraz: przegląd (`getData`)" source: https://docs.senuto.com/modules/visibility_analysis/va-history-keywords api: POST /api/visibility_analysis/reports/history/keywords/getData --- # Historia fraz: przegląd (`getData`) **`POST /api/visibility_analysis/reports/history/keywords/getData`** Zwraca frazy, na które domena rankowała w wybranym zakresie dat, wraz ze statystykami dla każdej frazy (pozycja, widoczność, URL, CPC, liczba wyszukiwań, trendy, trudność, snippety SERP) oraz osadzoną mapą `history` z historią pozycji. Użyj jej, aby sprawdzić, jak wyglądał zestaw fraz domeny i jej rankingi w wybranym oknie historycznym. Wyniki są sortowane według pojedynczej dyrektywy sortowania. | 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 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | zalando | 13624651 | b8ac304f24a9864f46f86cbebc0820f1 | zalando.pl | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 651480 | 651480 | 0 | 0 | zalando.pl/ | zalando.pl/ | 0 | 2.03 | 1830000 | [1830000,1830000,1830000,1830000,1830000,2240000,2240000,1830000,1830000,1500000,2240000,1830000] | | 71 | ["video_thumbs"] | _zalando.pl, sort: widoczność malejąco. 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/getData` 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": 10, "page": 1 } ``` **cURL** ```bash curl --location --request POST 'https://api.senuto.com/api/visibility_analysis/reports/history/keywords/getData' \ --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 HistoryKeywordsGetDataRequest = { /** * **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; stara wartość "domain" mapuje się tutaj) * - `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`. Musi być nie późniejszy niż dzisiaj i nie późniejszy niż `date_max`. */ date_min: string; /** * **Wymagane**. Koniec zakresu dat, `YYYY-MM-DD`. Musi być nie późniejszy niż dzisiaj i nie wcześniejszy niż `date_min`. */ date_max: string; /** * **Wymagane**. Id kraju (bazy danych). Polska = `1`. */ 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` */ 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; } export default HistoryKeywordsGetDataRequest ``` > **Ostrzeżenie:** > **`order` to pojedynczy obiekt** (`{ prop, dir }`) — nie tablica. Używaj ścieżek `prop` z kropkami wymienionych powyżej; dowolne inne pola są odrzucane. > **Ostrzeżenie:** > Pięć parametrów jest **wymaganych**: **`domain`**, **`fetch_mode`**, **`date_min`**, **`date_max`** oraz **`country_id`**, a także pojedynczy obiekt **`order`**. Pominięcie któregokolwiek wymaganego pola zwraca `418` z `invalid_data`. ## Filtrowanie Opcjonalny parametr `filtering` (tablica grup, filtry w grupie łączone operatorem AND) zawęża wyniki. Ten endpoint korzysta z **tego samego mechanizmu i tych samych kluczy filtrów co [Pozycje → Filtrowanie](/modules/visibility_analysis/positions#filtrowanie)** (dzielą komponent danych) — m.in. `keywords` (przez `items`: `contain`/`startsWith`/`endsWith`/`notContain`) oraz liczbowe `statistics.position.current`, `statistics.visibility.current`, `statistics.cpc.current`, `statistics.difficulty.current`, `statistics.searches.current`, `words_count` (`eq`/`gt`/`gte`/`lt`/`lte`). ```jsonc filename="żądanie-z-filtrowaniem.jsonc" { "domain": "zalando.pl", "fetch_mode": "topLevelDomain", "date_min": "2026-05-01", "date_max": "2026-06-29", "country_id": 1, "order": { "prop": "statistics.visibility.current", "dir": "desc" }, "filtering": [ { "filters": [ { "key": "statistics.position.current", "match": "lte", "value": 3 }, { "key": "keywords", "items": [{ "match": "contain", "value": "buty" }] } ] } ] } ``` > **Informacja:** > Zwalidowane na żywo (`zalando.pl`): bez filtra `count` = 300 894; z powyższym filtrem (TOP3 + fraza zawiera „buty") → `count` = 2 832. ## Odpowiedź W przypadku powodzenia otrzymujesz `data` (tablicę wierszy z frazami) oraz `pagination`. **Skrócona** ```json filename="przykładowa-odpowiedź (skrócona)" { "success": true, "data": [ { "keyword_id": 13624651, "keyword": "zalando", "statistics": { "position": { "current": 1 }, "visibility": { "current": 651480 } /* … */ } } ], "pagination": { "page_count": 145940, "current_page": 1, "has_next_page": true, "has_prev_page": false, "count": 291879, "limit": 10 } } ``` **Pełna** ```json filename="przykładowa-odpowiedź (200)" { "success": true, "data": [ { "keyword_id": 13624651, "kid": "b8ac304f24a9864f46f86cbebc0820f1", "domain": "zalando.pl", "keyword": "zalando", "words_count": 1, "statistics": { "position": { "current": 1, "previous": 1, "diff": 0, "changes": { "wins": 0, "losses": 0, "no_changes": 0 }, "history": { "2026-06-02": { "position": 1, "has_serp": true } } }, "visibility": { "current": 651480, "previous": 651480, "diff": 0, "percent": 0, "history": null }, "url": { "current": "zalando.pl/", "previous": "zalando.pl/", "is_change": 0 }, "cpc": { "current": 2.03 }, "searches": { "current": 1830000 }, "trends": { "history": [1830000, 1830000, 1830000, 1830000, 1830000, 2240000, 2240000, 1830000, 1830000, 1500000, 2240000, 1830000], "peak": null }, "difficulty": { "current": 71 }, "snippets": { "current": ["video_thumbs"] } } } ], "pagination": { "page_count": 145940, "current_page": 1, "has_next_page": true, "has_prev_page": false, "count": 291879, "limit": 10 } } ``` ### Struktura odpowiedzi ```ts type HistoryKeywordsResponse = { /** `true` przy powodzeniu; przy błędzie `false` i koperta z `error` */ success: boolean; /** Zwrócone wiersze z frazami */ data: KeywordRow[]; /** Metadane paginacji */ pagination: { page_count: number; current_page: number; has_next_page: boolean; has_prev_page: boolean; count: number; limit: number; }; } type KeywordRow = { keyword_id: number; kid: string; domain: string; keyword: string; words_count: number; statistics: { position: { current: number; previous: number; diff: number; changes: { wins: number; losses: number; no_changes: number }; history: Record | [] }; visibility: { current: number; previous: number; diff: number; percent: number; history: null }; url: { current: string; previous: string; is_change: 0 | 1 }; cpc: { current: number }; searches: { current: number }; trends: { history: number[]; peak: number | null }; difficulty: { current: number }; snippets: { current: string[] }; }; } export default HistoryKeywordsResponse ``` ## Błędy ```ts type ErrorResponse = { success: false; data: { error: { /** np. invalid_data, invalid_filtering, database, timeout, unknown */ type: string; message: string; /** pole -> reguła -> komunikat (dla invalid_data) */ params?: Record>; }; }; } export default ErrorResponse ``` > **Błąd:** > **`418`** zwracany jest również dla błędów walidacji — nie tylko przy ograniczeniu liczby żądań (rate limiting). Brak wymaganego pola → > `{"success":false,"data":{"error":{"type":"invalid_data","params":{"country_id":{"_required":"This field is required"}}}}}`. > > **Znany błąd — mylący komunikat.** Gdy zakres dat jest poprawny (`date_min <= date_max`), ale wystąpi naruszenie `DateRangeRules`, zwrócony komunikat brzmi `"date_max must be less or equal than date_min"`. Treść jest błędna (sama logika działa poprawnie) — należy go odczytywać jako niepowodzenie reguły zakresu dat, a nie jako dosłowną instrukcję. ## Powiązane akcje - `getData` — frazy w zakresie dat (`MODE_DATA`, ta strona) - `getWins` / `getLosses` — frazy, które zyskały / straciły pozycje w danym zakresie (taka sama struktura żądania) - `getAcquired` / `getLost` — frazy nowo pozyskane / całkowicie utracone w zakresie (taka sama struktura żądania) - `getDates` — dostępne daty dla zakresu (lżejsze wywołanie, używa osobnego walidatora)