--- title: "Pozycje: dane (`getData`)" source: https://docs.senuto.com/modules/rank_tracker/rt-positions-getData api: POST /api/rank_tracker/reports/positions/getData --- # Pozycje: dane (`getData`) **`POST /api/rank_tracker/reports/positions/getData`** Zwraca monitorowane słowa kluczowe projektu Rank Tracker dla wybranego zakresu dat, wraz z pozycjami dla każdego słowa kluczowego, historią pozycji, widocznością, CPC, liczbą wyszukiwań, snippetami SERP oraz podziałem na desktop/mobile. | Fraza | ID | KID | Status | Widoczność org. | Widoczność org. poprz. | Δ widoczności org. | Potencjał org. | Δ pozycji org. | CPC | Wyszukiwania/mies. | Rankujący URL | Pozycja bieżąca | Pozycja ostatnia | Zmiana pozycji | Pozycja wczoraj | Pierwsza pozycja | Data pierwszej pozycji | Aktualizacja (data) | Aktualizacja (timestamp) | Wzrosty | Spadki | Bez zmian | Snippety SERP | Pozycja desktop | Pozycja mobile | Zakres: pierwsza | Zakres: ostatnia | Zakres: różnica | Poz. pierwsza | Poz. bieżąca | Poz. poprzednia | Poz. różnica | Poz. wzrosty | Poz. spadki | Poz. bez zmian | Poz. początek zakresu | Poz. koniec zakresu | Widoczność bieżąca | Widoczność poprz. | Δ widoczności | CPC (statystyki) | Wyszukiwania (statystyki) | URL (statystyki) | Snippety (statystyki) | Mapy aktywne | Mapy | Bezpośr. odpowiedzi aktywne | Bezpośr. odpowiedzi | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | slowa kluczowe | 3025571 | 95b343081f25ecf51403b940b739bf78 | complete | 140 | 228 | -88 | 463 | 1 | 6.34 | 1300 | https://www.senuto.com/pl/blog/slowa-kluczowe/ | 3 | 2 | 1 | 2 | 27 | | 2026-06-30 | 1782797439 | 3 | 3 | 3 | ["ai_overview","people_also_ask","featured_snippets"] | 2 | | 3 | 2 | 1 | 27 | 3 | 2 | 1 | 4 | 3 | 2 | 3 | 2 | 139.75 | 227.76 | -88.01 | 6.34 | 1300 | https://www.senuto.com/pl/blog/slowa-kluczowe/ | ["ai_overview","people_also_ask"] | | | | | _projekt Rank Trackera, zakres 2026-06-20 – 2026-06-29, limit: 2. Uwaga na niespójne typy: searches, current_position i diff_position to stringi, a cpc jest liczbą. Wszystkie adresowalne pola wiersza (pominięto mapy o zmiennych kluczach-datach: positions, desktop.positions_history, desktop.history, mobile.positions_history, mobile.history — są w JSON i sekcji „Struktura odpowiedzi”)._ --- ## Żądanie `POST` `/api/rank_tracker/reports/positions/getData` Nagłówki: `Authorization: Bearer `, `Content-Type: application/json`. ### Struktura żądania **Podstawowy** ```jsonc filename="żądanie-podstawowe.jsonc" { "project_id": null, "date_min": "2026-06-20", "date_max": "2026-06-29", "limit": 2, "page": 1 } ``` **Rozszerzony** ```jsonc filename="żądanie-rozszerzone.jsonc" { "project_id": null, "date_min": "2026-06-20", "date_max": "2026-06-29", "group_id": 0, "page": 1, "limit": 2, "mode": "desktop", "order": { "prop": "statistics.positions_date_range.last", "value": "asc" }, "filtering": [] } ``` **cURL** ```bash curl --location --request POST 'https://api.senuto.com/api/rank_tracker/reports/positions/getData' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer $YOUR_TOKEN_HERE' \ --data-raw '{ "project_id": null, "date_min": "2026-06-20", "date_max": "2026-06-29", "limit": 2, "page": 1 }' ``` ### Parametry ```ts type RtPositionsGetDataRequest = { /** * **Wymagane**. ID projektu Rank Tracker. Liczba całkowita nieujemna. Musisz mieć dostęp * do projektu (jako właściciel, administrator lub poprzez udostępnienie ACL) — w przeciwnym razie `Unauthorized access`. * Listę swoich projektów pobierzesz: `POST /api/rank_tracker/management/projects/getMyActiveProjects`. */ project_id: number; /** * **Wymagane**. Początek zakresu dat, format `YYYY-mm-dd`. * Musi być `<= date_max` oraz `<= today`. */ date_min: string; /** * **Wymagane**. Koniec zakresu dat, format `YYYY-mm-dd`. * Musi być `>= date_min` oraz `<= today`. */ date_max: string; /** * ID grupy słów kluczowych w projekcie. Gdy ustawione, raport zwraca pozycje * dla tej grupy zamiast dla całego projektu. * @default 0 */ group_id?: number; /** * ID konkurenta. Gdy ustawione, raport zwraca pozycje dla tego konkurenta * (w obrębie projektu lub grupy). */ competitor_id?: number; /** * Numer strony. Liczba całkowita nieujemna. * @default 1 */ page?: number; /** * Liczba wierszy na stronę. Liczba całkowita nieujemna (maxLimit kontrolera = 10000). * @default 10 */ limit?: number; /** * Tryb pobierania pozycji (urządzenie). Po stronie serwera zamieniane na małe litery. * @default 'desktop' */ mode?: 'desktop' | 'mobile'; /** * Sortowanie. Obiekt z `prop` (np. `statistics.positions_date_range.last` / * `.first` — wtedy `value` jest automatycznie uzupełniane z `date_max` / `date_min`) oraz `value`. */ order?: { prop: string; value: string }; /** * Filtrowanie — tablica grup (filtry w grupie łączone AND). Zwalidowany klucz: * `keywords` (filtr tekstowy przez `items`: match `contain`/`startsWith`/`endsWith`/`exact`/`notContain`). * Szczegóły i pełny mechanizm: sekcja "Filtrowanie" poniżej oraz [`Filter`](/types/filter). */ filtering?: { filters: { key: 'keywords'; items: { value: string; match: 'contain' | 'startsWith' | 'endsWith' | 'exact' | 'notContain' }[] }[]; }[]; } export default RtPositionsGetDataRequest ``` > **Ostrzeżenie:** > Warianty **`wins`** / **`losses`** **nie** są parametrem w treści żądania — to segment URL (argument `typeWinsOrLosses` akcji): `…/getData` (pełny raport), `…/getData/wins` (słowa kluczowe, które zyskały od wczoraj), `…/getData/losses` (słowa kluczowe, które spadły). Odpowiednik eksportu: `/api/rank_tracker/reports/exports/positions/getData[/wins|/losses]`. > **Ostrzeżenie:** > Wymagane pola w treści żądania to **`project_id`**, **`date_min`** i **`date_max`** (daty w formacie `YYYY-mm-dd`, obie `<= today`, przy czym `date_min <= date_max`). W przeciwieństwie do Analizy widoczności, Rank Tracker **nie** używa `domain` / `fetch_mode` — operuje na **`project_id`** (plus opcjonalnie `group_id` / `competitor_id`). Ścieżka jest w **snake\_case** i kanoniczna pod `/api/rank_tracker/…`. Warianty **`wins`** / **`losses`** to **segmenty URL**, a nie pola w treści żądania: `…/getData/wins` i `…/getData/losses`. Błędy walidacji zwracają **`418`** (`invalid_data`). ## Filtrowanie Opcjonalny parametr `filtering` odpowiada polu **Filtry** nad tabelą w raporcie pozycji projektu. To tablica grup; filtry w grupie łączone są operatorem AND (zob. wspólny [`Filter`](/types/filter)). Zwalidowany klucz dla tego endpointu to **`keywords`** (filtr tekstowy przez `items`): ```jsonc filename="żądanie-z-filtrowaniem.jsonc" { "project_id": null, "date_min": "2026-06-17", "date_max": "2026-06-30", "filtering": [ { "filters": [ { "key": "keywords", "items": [{ "value": "pies", "match": "startsWith" }] } ] } ] } ``` Operatory `match` dla `keywords`: `contain`, `startsWith`, `endsWith`, `exact`, `notContain`. > **Informacja:** > Zwalidowane na żywo (projekt `124572`): bez filtra `count` = 395; z filtrem `keywords startsWith "pies"` → `count` = 8 (frazy „pies berneńczyk", „pies rysunek"…). Aplikacja dołącza do filtra opcjonalne `type: "string"` i `filterSourceType: "customFilter"` — API działa też bez nich. ## Odpowiedź Po pomyślnym żądaniu otrzymujesz `data` (tablica wierszy słów kluczowych) oraz `pagination`. Zwróć uwagę, że kilka pól liczbowych zwracanych jest jako **ciągi znaków** (np. `searches`, `current_position`, `diff_position`, `first_position`, `id`), podczas gdy `organic_visibility` / `organic_potential` / `cpc` są liczbami — typowanie jest niespójne. **Skrócona** ```json filename="przykładowa-odpowiedź (skrócona)" { "success": true, "data": [ { "id": "3025571", "keyword": "slowa kluczowe", "current_position": "3", "last_position": 2, "positions": { "2026-06-20": 3, "2026-06-28": 2, "2026-06-29": 2 }, "statistics": { "positions_date_range": { "first": 3, "last": 2, "diff": 1 } } } ], "pagination": { "page_count": 198, "current_page": 1, "has_next_page": true, "has_prev_page": false, "count": 395, "limit": 2 } } ``` **Pełna** ```json filename="przykładowa-odpowiedź (200)" { "success": true, "data": [ { "id": "3025571", "kid": "95b343081f25ecf51403b940b739bf78", "status": "complete", "organic_visibility": 140, "organic_visibility_old": 228, "organic_visibility_diff": -88, "organic_potential": 463, "organic_pos_diff": "1", "updated": { "date": "2026-06-30", "timestamp": 1782797439 }, "cpc": 6.34, "keyword": "slowa kluczowe", "searches": "1300", "url": "https://www.senuto.com/pl/blog/slowa-kluczowe/", "positions": { "2026-06-20": 3, "2026-06-28": 2, "2026-06-29": 2 }, "current_position": "3", "last_position": 2, "diff_position": "1", "pos_yesterday": "2", "positions_changes": { "grows": 3, "losses": 3, "no_changes": 3 }, "snippets": ["ai_overview", "people_also_ask", "featured_snippets"], "first_position": "27", "first_date": "", "desktop": { "position": 2, "positions_history": { "2026-06-29": 2 }, "history": { "2026-06-29": { "url": "https://www.senuto.com/pl/blog/slowa-kluczowe/", "pos": 2, "v": 227.76, "has_serp": true } } }, "mobile": { "position": null, "positions_history": { "2026-06-29": null }, "history": { "2026-06-29": { "url": null, "pos": null, "v": 0, "has_serp": true } } }, "statistics": { "positions_date_range": { "first": 3, "last": 2, "diff": 1 }, "position": { "first": 27, "current": 3, "previous": 2, "diff": 1, "changes": { "wins": 4, "losses": 3, "no_changes": 2 }, "range_start": 3, "range_end": 2 }, "visibility": { "current": 139.75, "previous": 227.76, "diff": -88.01 }, "cpc": { "current": 6.34 }, "searches": { "current": "1300" }, "url": { "current": "https://www.senuto.com/pl/blog/slowa-kluczowe/" }, "snippets": { "current": ["ai_overview", "people_also_ask"] } }, "serp_features": { "maps_active": null, "maps": null, "direct_answers_active": null, "direct_answers": null } } ], "pagination": { "page_count": 198, "current_page": 1, "has_next_page": true, "has_prev_page": false, "count": 395, "limit": 2 } } ``` ### Struktura odpowiedzi ```ts type RtPositionsResponse = { /** `true` przy powodzeniu; przy błędzie `false` i koperta z `error` */ success: boolean; /** Zwrócone wiersze słów kluczowych */ data: RtPositionRow[]; /** Metadane paginacji */ pagination: { page_count: number; current_page: number; has_next_page: boolean; has_prev_page: boolean; count: number; limit: number; }; } type RtPositionRow = { /** ID wiersza słowa kluczowego — zwracane jako ciąg znaków */ id: string; kid: string; status: string; organic_visibility: number; organic_visibility_old: number; organic_visibility_diff: number; organic_potential: number; /** Zwracane jako ciąg znaków */ organic_pos_diff: string; updated: { date: string; timestamp: number }; cpc: number; keyword: string; /** Miesięczna liczba wyszukiwań — zwracane jako ciąg znaków */ searches: string; url: string; /** Mapa data -> pozycja dla wybranego zakresu */ positions: Record; /** Zwracane jako ciąg znaków */ current_position: string; last_position: number; /** Zwracane jako ciąg znaków */ diff_position: string; /** Zwracane jako ciąg znaków */ pos_yesterday: string; positions_changes: { grows: number; losses: number; no_changes: number }; snippets: string[]; /** Zwracane jako ciąg znaków */ first_position: string; first_date: string; desktop: RtDeviceBlock; mobile: RtDeviceBlock; statistics: { positions_date_range: { first: number; last: number; diff: number }; position: { first: number; current: number; previous: number; diff: number; changes: { wins: number; losses: number; no_changes: number }; range_start: number; range_end: number }; visibility: { current: number; previous: number; diff: number }; cpc: { current: number }; searches: { current: string }; url: { current: string }; snippets: { current: string[] }; }; serp_features: { maps_active: number | null; maps: unknown | null; direct_answers_active: number | null; direct_answers: unknown | null }; } type RtDeviceBlock = { position: number | null; positions_history: Record; history: Record; } export default RtPositionsResponse ``` ## Błędy ```ts type ErrorResponse = { success: false; data: { error: { /** np. invalid_data, unreachable_data, timeout, database, unknown */ type: string; message: string; /** pole -> reguła -> komunikat (dla invalid_data) */ params?: Record>; }; }; } export default ErrorResponse ``` > **Błąd:** > **`418`** zwracane jest również dla błędów walidacji — nie tylko dla ograniczeń liczby zapytań. Brakujące lub źle sformatowane `project_id` / `date_min` / `date_max` skutkuje `invalid_data` wraz z mapą `params`. Zwróć uwagę na znany **błąd w treści komunikatu** dla reguły zakresu: brzmi on `date_max must be less or equal than date_min`, ale logika jest poprawna (`date_min <= date_max`). Projekt, do którego nie masz dostępu, zwraca `Unauthorized access`. ## Powiązane akcje - `getData` — bieżące pozycje dla projektu (ta strona) - `getData/wins` / `getData/losses` — słowa kluczowe, które zyskały / straciły pozycje względem wczoraj (segment URL, ta sama treść żądania) - `POST /api/rank_tracker/management/projects/getMyActiveProjects` — pobranie listy swoich projektów, aby uzyskać `project_id` (zwraca `{ id, domain, name }`) - `/api/rank_tracker/reports/exports/positions/getData[/wins|/losses]` — odpowiednik tego raportu w formie eksportu