openapi: 3.0.3 info: title: 'Crawler API - Deklaracje Dostępności' description: 'API do wyszukiwania deklaracji dostępności na stronach instytucji publicznych.' version: 1.0.0 servers: - url: 'https://crawler.deklaracja-dostepnosci.info//api' tags: - name: 'Crawler API' description: '' - name: 'A11Y FastScan' description: '' - name: 'Jobs Management' description: '' paths: /api/find-declaration: get: summary: 'Wyszukiwanie deklaracji dostępności' operationId: wyszukiwanieDeklaracjiDostpnoci description: "Endpoint automatycznie wyszukuje deklarację dostępności na podanej stronie internetowej.\nWykorzystuje wielopoziomową strategię wyszukiwania:\n1. Pattern matching - szukanie według wzorcow tekstowych i linków\n2. AI analysis - analiza treści przez model językowy (opcjonalne)\n3. JavaScript rendering - renderowanie stron dynamicznych przez Playwright (opcjonalne)" parameters: - in: query name: url description: 'URL strony do przeszukania. Musi zaczynać się od http:// lub https://.' example: 'https://example.gov.pl' required: true schema: type: string description: 'URL strony do przeszukania. Musi zaczynać się od http:// lub https://.' example: 'https://example.gov.pl' nullable: false - in: query name: domain_id description: 'ID domeny w systemie. Używane do archiwizacji wyników.' example: 123 required: false schema: type: integer description: 'ID domeny w systemie. Używane do archiwizacji wyników.' example: 123 nullable: false - in: query name: timeout description: 'Timeout w sekundach dla pobierania stron (5-120). Default: 30.' example: 60 required: false schema: type: integer description: 'Timeout w sekundach dla pobierania stron (5-120). Default: 30.' example: 60 nullable: false - in: query name: max_depth description: 'Głębokość przeszukiwania podstron (1-2). Default: 2.' example: 2 required: false schema: type: integer description: 'Głębokość przeszukiwania podstron (1-2). Default: 2.' example: 2 nullable: false - in: query name: use description: 'Metody do użycia podczas wyszukiwania. Możliwe wartości: render_js (renderowanie JavaScript przez Playwright), ai (analiza przez AI), smart_fetch (inteligentne pobieranie z fallback).' example: - ai - render_js required: false schema: type: array description: 'Metody do użycia podczas wyszukiwania. Możliwe wartości: render_js (renderowanie JavaScript przez Playwright), ai (analiza przez AI), smart_fetch (inteligentne pobieranie z fallback).' example: - ai - render_js items: type: string - in: query name: follow_redirects description: 'Czy śledzić przekierowania HTTP. Default: true.' example: true required: false schema: type: boolean description: 'Czy śledzić przekierowania HTTP. Default: true.' example: true nullable: false responses: 200: description: '' content: application/json: schema: oneOf: - description: 'Znaleziono deklarację' type: object example: code: 200 status: success page: url: 'https://example.gov.pl' title: 'Przykładowa Instytucja' links_count: 42 content_size: 15234 dd: found: true url: 'https://example.gov.pl/deklaracja-dostepnosci' title: 'Deklaracja dostępności' score: 85 method: pattern search_level: 1 validation: is_valid: true has_required_elements: true wcag_version: '2.1' conformance_level: AA properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: url: type: string example: 'https://example.gov.pl' title: type: string example: 'Przykładowa Instytucja' links_count: type: integer example: 42 content_size: type: integer example: 15234 dd: type: object properties: found: type: boolean example: true url: type: string example: 'https://example.gov.pl/deklaracja-dostepnosci' title: type: string example: 'Deklaracja dostępności' score: type: integer example: 85 method: type: string example: pattern search_level: type: integer example: 1 validation: type: object properties: is_valid: type: boolean example: true has_required_elements: type: boolean example: true wcag_version: type: string example: '2.1' conformance_level: type: string example: AA - description: 'Nie znaleziono deklaracji' type: object example: code: 200 status: success page: url: 'https://example.gov.pl' title: 'Przykładowa Instytucja' links_count: 42 content_size: 15234 dd: found: false url: null search_level: 2 pages_checked: 5 method: exhaustive properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: url: type: string example: 'https://example.gov.pl' title: type: string example: 'Przykładowa Instytucja' links_count: type: integer example: 42 content_size: type: integer example: 15234 dd: type: object properties: found: type: boolean example: false url: type: string example: null search_level: type: integer example: 2 pages_checked: type: integer example: 5 method: type: string example: exhaustive - description: '' type: object example: code: 200 status: success page: url: 'https://example.gov.pl' final_url: 'https://example.gov.pl' title: 'Urząd Przykładowy - Strona główna' links_count: 47 content_size: 18432 fetch_time: 0.842 rendered_with: http meta: description: 'Oficjalna strona Urzędu Przykładowego' keywords: 'urząd, instytucja publiczna, administracja' dd: found: true url: 'https://example.gov.pl/deklaracja-dostepnosci' title: 'Deklaracja dostępności' score: 92 method: pattern search_level: 1 pages_checked: 1 validation: is_valid: true has_required_elements: true wcag_version: '2.1' conformance_level: AA elements_found: - 'status zgodności' - 'data sporządzenia' - 'dane kontaktowe' - 'procedura skargowa' metadata: publication_date: '2024-01-15' last_update: '2024-09-01' entity_name: 'Urząd Przykładowy' contact_email: dostepnosc@example.gov.pl properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: url: type: string example: 'https://example.gov.pl' final_url: type: string example: 'https://example.gov.pl' title: type: string example: 'Urząd Przykładowy - Strona główna' links_count: type: integer example: 47 content_size: type: integer example: 18432 fetch_time: type: number example: 0.842 rendered_with: type: string example: http meta: type: object properties: description: type: string example: 'Oficjalna strona Urzędu Przykładowego' keywords: type: string example: 'urząd, instytucja publiczna, administracja' dd: type: object properties: found: type: boolean example: true url: type: string example: 'https://example.gov.pl/deklaracja-dostepnosci' title: type: string example: 'Deklaracja dostępności' score: type: integer example: 92 method: type: string example: pattern search_level: type: integer example: 1 pages_checked: type: integer example: 1 validation: type: object properties: is_valid: type: boolean example: true has_required_elements: type: boolean example: true wcag_version: type: string example: '2.1' conformance_level: type: string example: AA elements_found: type: array example: - 'status zgodności' - 'data sporządzenia' - 'dane kontaktowe' - 'procedura skargowa' items: type: string metadata: type: object properties: publication_date: type: string example: '2024-01-15' last_update: type: string example: '2024-09-01' entity_name: type: string example: 'Urząd Przykładowy' contact_email: type: string example: dostepnosc@example.gov.pl - description: '' type: object example: code: 200 status: success page: url: 'https://example.com' final_url: 'https://example.com' title: 'Przykładowa Firma - Strona główna' links_count: 32 content_size: 12845 fetch_time: 0.523 rendered_with: http meta: description: 'Strona firmowa Example' keywords: 'firma, usługi, przykład' dd: found: false url: null search_level: 2 pages_checked: 8 method: exhaustive searched_urls: - 'https://example.com' - 'https://example.com/kontakt' - 'https://example.com/o-nas' - 'https://example.com/polityka-prywatnosci' - 'https://example.com/regulamin' - 'https://example.com/dostepnosc' - 'https://example.com/accessibility' - 'https://example.com/deklaracja' potential_matches: [] reason: 'Nie znaleziono strony zawierającej deklarację dostępności ani linków pasujących do wzorców' properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: url: type: string example: 'https://example.com' final_url: type: string example: 'https://example.com' title: type: string example: 'Przykładowa Firma - Strona główna' links_count: type: integer example: 32 content_size: type: integer example: 12845 fetch_time: type: number example: 0.523 rendered_with: type: string example: http meta: type: object properties: description: type: string example: 'Strona firmowa Example' keywords: type: string example: 'firma, usługi, przykład' dd: type: object properties: found: type: boolean example: false url: type: string example: null search_level: type: integer example: 2 pages_checked: type: integer example: 8 method: type: string example: exhaustive searched_urls: type: array example: - 'https://example.com' - 'https://example.com/kontakt' - 'https://example.com/o-nas' - 'https://example.com/polityka-prywatnosci' - 'https://example.com/regulamin' - 'https://example.com/dostepnosc' - 'https://example.com/accessibility' - 'https://example.com/deklaracja' items: type: string potential_matches: type: array example: [] reason: type: string example: 'Nie znaleziono strony zawierającej deklarację dostępności ani linków pasujących do wzorców' 422: description: 'Błąd walidacji' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: url: - 'URL jest wymagany' - 'URL musi zaczynać się od http:// lub https://' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: url: type: array example: - 'URL jest wymagany' - 'URL musi zaczynać się od http:// lub https://' items: type: string 500: description: 'Błąd serwera' content: application/json: schema: type: object example: code: 500 status: error message: 'Wystąpił błąd podczas przetwarzania żądania' properties: code: type: integer example: 500 status: type: string example: error message: type: string example: 'Wystąpił błąd podczas przetwarzania żądania' tags: - 'Crawler API' requestBody: required: true content: application/json: schema: type: object properties: url: type: string description: 'Must be a valid URL. Must match the regex /^https?:\/\//.' example: 'http://' nullable: false domain_id: type: integer description: validation.min. example: 31 nullable: true timeout: type: integer description: 'validation.min validation.max.' example: 14 nullable: true follow_redirects: type: boolean description: '' example: true nullable: true use: type: array description: '' example: - render_js items: type: string enum: - render_js - ai - smart_fetch _: type: integer description: '' example: 4 nullable: true exclude: type: array description: '' example: - meta items: type: string enum: - content - links - meta save_to_temp_file: type: boolean description: '' example: true nullable: true type: type: string description: '' example: page nullable: true enum: - hp - page - link max_depth: type: integer description: 'validation.min validation.max.' example: 1 nullable: true required: - url security: [] /api/fetch-page: get: summary: 'Pobieranie zawartości strony' operationId: pobieranieZawartociStrony description: "Pobiera i analizuje zawartość strony internetowej z opcjonalnym renderowaniem JavaScript.\nZwraca pełną treść strony wraz z wyodrębnionymi linkami i metadanymi." parameters: - in: query name: url description: 'URL strony do pobrania.' example: 'https://example.gov.pl/about' required: true schema: type: string description: 'URL strony do pobrania.' example: 'https://example.gov.pl/about' nullable: false - in: query name: timeout description: 'Timeout w sekundach dla pobierania strony (5-120). Default: 30.' example: 30 required: false schema: type: integer description: 'Timeout w sekundach dla pobierania strony (5-120). Default: 30.' example: 30 nullable: false - in: query name: use description: 'Metody renderowania strony. Możliwe wartości: render_js (renderowanie JavaScript przez Playwright).' example: - render_js required: false schema: type: array description: 'Metody renderowania strony. Możliwe wartości: render_js (renderowanie JavaScript przez Playwright).' example: - render_js items: type: string - in: query name: follow_redirects description: 'Czy śledzić przekierowania HTTP. Default: true.' example: true required: false schema: type: boolean description: 'Czy śledzić przekierowania HTTP. Default: true.' example: true nullable: false responses: 200: description: '' content: application/json: schema: oneOf: - description: Sukces type: object example: code: 200 status: success page: url: 'https://example.gov.pl/about' final_url: 'https://example.gov.pl/o-nas' title: 'O nas - Przykładowa Instytucja' content: '...' links: - url: 'https://example.gov.pl/kontakt' text: Kontakt title: 'Skontaktuj się z nami' - url: 'https://example.gov.pl/deklaracja-dostepnosci' text: 'Deklaracja dostępności' meta: description: 'Informacje o naszej instytucji' keywords: 'instytucja publiczna, urząd' rendered_with: playwright fetch_time: 1.234 properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: url: type: string example: 'https://example.gov.pl/about' final_url: type: string example: 'https://example.gov.pl/o-nas' title: type: string example: 'O nas - Przykładowa Instytucja' content: type: string example: '...' links: type: array example: - url: 'https://example.gov.pl/kontakt' text: Kontakt title: 'Skontaktuj się z nami' - url: 'https://example.gov.pl/deklaracja-dostepnosci' text: 'Deklaracja dostępności' items: type: object properties: url: type: string example: 'https://example.gov.pl/kontakt' text: type: string example: Kontakt title: type: string example: 'Skontaktuj się z nami' meta: type: object properties: description: type: string example: 'Informacje o naszej instytucji' keywords: type: string example: 'instytucja publiczna, urząd' rendered_with: type: string example: playwright fetch_time: type: number example: 1.234 - description: '' type: object example: code: 200 status: success page: url: 'https://example.gov.pl/o-nas' final_url: 'https://example.gov.pl/o-nas' title: 'O nas - Urząd Przykładowy' content: "\n\n\n \n O nas - Urząd Przykładowy\n \n\n\n
\n

Urząd Przykładowy

\n \n
\n
\n

O Urzędzie

\n

Urząd Przykładowy jest jednostką administracji publicznej...

\n
\n \n\n" links: - url: 'https://example.gov.pl/' text: 'Strona główna' title: null alt: null - url: 'https://example.gov.pl/o-nas' text: 'O nas' title: null alt: null - url: 'https://example.gov.pl/kontakt' text: Kontakt title: null alt: null - url: 'https://example.gov.pl/deklaracja-dostepnosci' text: 'Deklaracja dostępności' title: null alt: null meta: description: 'Informacje o Urzędzie Przykładowym' charset: UTF-8 viewport: 'width=device-width, initial-scale=1.0' rendered_with: playwright fetch_time: 2.156 content_type: 'text/html; charset=UTF-8' status_code: 200 properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: url: type: string example: 'https://example.gov.pl/o-nas' final_url: type: string example: 'https://example.gov.pl/o-nas' title: type: string example: 'O nas - Urząd Przykładowy' content: type: string example: "\n\n\n \n O nas - Urząd Przykładowy\n \n\n\n
\n

Urząd Przykładowy

\n \n
\n
\n

O Urzędzie

\n

Urząd Przykładowy jest jednostką administracji publicznej...

\n
\n \n\n" links: type: array example: - url: 'https://example.gov.pl/' text: 'Strona główna' title: null alt: null - url: 'https://example.gov.pl/o-nas' text: 'O nas' title: null alt: null - url: 'https://example.gov.pl/kontakt' text: Kontakt title: null alt: null - url: 'https://example.gov.pl/deklaracja-dostepnosci' text: 'Deklaracja dostępności' title: null alt: null items: type: object properties: url: type: string example: 'https://example.gov.pl/' text: type: string example: 'Strona główna' title: type: string example: null alt: type: string example: null meta: type: object properties: description: type: string example: 'Informacje o Urzędzie Przykładowym' charset: type: string example: UTF-8 viewport: type: string example: 'width=device-width, initial-scale=1.0' rendered_with: type: string example: playwright fetch_time: type: number example: 2.156 content_type: type: string example: 'text/html; charset=UTF-8' status_code: type: integer example: 200 404: description: 'Strona nie istnieje' content: application/json: schema: type: object example: code: 404 status: error message: 'Nie można pobrać strony: 404 Not Found' properties: code: type: integer example: 404 status: type: string example: error message: type: string example: 'Nie można pobrać strony: 404 Not Found' 422: description: 'Błąd walidacji' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: url: - 'URL jest wymagany' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: url: type: array example: - 'URL jest wymagany' items: type: string 500: description: 'Błąd serwera' content: application/json: schema: type: object example: code: 500 status: error message: 'Wystąpił błąd podczas pobierania strony' properties: code: type: integer example: 500 status: type: string example: error message: type: string example: 'Wystąpił błąd podczas pobierania strony' tags: - 'Crawler API' requestBody: required: true content: application/json: schema: type: object properties: url: type: string description: 'Must be a valid URL. Must match the regex /^https?:\/\//.' example: 'https://' nullable: false domain_id: type: integer description: validation.min. example: 42 nullable: true timeout: type: integer description: 'validation.min validation.max.' example: 7 nullable: true follow_redirects: type: boolean description: '' example: true nullable: true use: type: array description: '' example: - render_js items: type: string enum: - render_js - ai - smart_fetch _: type: integer description: '' example: 10 nullable: true exclude: type: array description: '' example: - links items: type: string enum: - content - links - meta save_to_temp_file: type: boolean description: '' example: false nullable: true type: type: string description: '' example: page nullable: true enum: - hp - page - link required: - url security: [] /api/scan-accessibility: get: summary: 'Analiza dostępności (WCAG/A11y) strony' operationId: analizaDostpnociWCAGA11yStrony description: "Endpoint analizuje dostępność cyfrową strony internetowej za pomocą axe-core.\nZwraca naruszenia WCAG, testy które przeszły oraz elementy wymagające manualnej weryfikacji.\nAnaliza wykonywana jest zawsze w przeglądarce (Playwright) dla maksymalnej dokładności.\n\n## Metody HTTP\n- **GET** - dla prostych zapytań z URL (query params)\n- **POST** - dla zaawansowanych zapytań (body params)\n\n## Parametry array\n- Array syntax: `?tags[]=wcag2aa&tags[]=wcag21aa` lub `?tags=wcag2aa` (auto-normalizacja)\n- W POST: `{\"tags\": [\"wcag2aa\", \"wcag21aa\"]}`" parameters: - in: query name: url description: 'URL strony do analizy.' example: 'https://example.gov.pl' required: true schema: type: string description: 'URL strony do analizy.' example: 'https://example.gov.pl' nullable: false - in: query name: domain_id description: 'ID domeny w systemie (opcjonalny).' example: 123 required: false schema: type: integer description: 'ID domeny w systemie (opcjonalny).' example: 123 nullable: false - in: query name: use description: 'Metody pobierania strony i analiz: smart_fetch (Playwright), ai (analiza AI naruszeń).' example: - smart_fetch - ai required: false schema: type: array description: 'Metody pobierania strony i analiz: smart_fetch (Playwright), ai (analiza AI naruszeń).' example: - smart_fetch - ai items: type: string - in: query name: timeout description: 'Timeout w sekundach (5-120). Default: 30.' example: 30 required: false schema: type: integer description: 'Timeout w sekundach (5-120). Default: 30.' example: 30 nullable: false - in: query name: include description: 'Które wyniki zwrócić: violations, passes, incomplete, inapplicable. Default: violations.' example: null required: false schema: type: array description: 'Które wyniki zwrócić: violations, passes, incomplete, inapplicable. Default: violations.' example: null items: type: string - in: query name: tags description: 'Filtry WCAG: wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa, best-practice.' example: null required: false schema: type: array description: 'Filtry WCAG: wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa, best-practice.' example: null items: type: string - in: query name: save_to_temp_file description: 'Zapisz content do pliku tymczasowego. Default: true.' example: true required: false schema: type: boolean description: 'Zapisz content do pliku tymczasowego. Default: true.' example: true nullable: false - in: query name: type description: 'Typ strony (page, hp, link). Default: page.' example: page required: false schema: type: string description: 'Typ strony (page, hp, link). Default: page.' example: page nullable: false responses: 200: description: '' content: application/json: schema: oneOf: - description: 'Znaleziono naruszenia' type: object example: code: 200 status: success page: url: 'https://example.gov.pl' final_url: 'https://example.gov.pl' code: 200 content_type: text/html speed: 1.234 a11y: success: true results: violations: - id: color-contrast impact: serious description: 'Elements must have sufficient color contrast' url: 'https://example.gov.pl' timestamp: '2025-09-30T12:00:00Z' properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: url: type: string example: 'https://example.gov.pl' final_url: type: string example: 'https://example.gov.pl' code: type: integer example: 200 content_type: type: string example: text/html speed: type: number example: 1.234 a11y: type: object properties: success: type: boolean example: true results: type: object properties: violations: type: array example: - { id: color-contrast, impact: serious, description: 'Elements must have sufficient color contrast' } items: type: object properties: { id: { type: string, example: color-contrast }, impact: { type: string, example: serious }, description: { type: string, example: 'Elements must have sufficient color contrast' } } url: type: string example: 'https://example.gov.pl' timestamp: type: string example: '2025-09-30T12:00:00Z' - description: 'Brak naruszeń' type: object example: code: 200 status: success page: url: 'https://example.gov.pl' code: 200 a11y: success: true results: violations: [] url: 'https://example.gov.pl' properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: url: type: string example: 'https://example.gov.pl' code: type: integer example: 200 a11y: type: object properties: success: type: boolean example: true results: type: object properties: violations: type: array example: [] url: type: string example: 'https://example.gov.pl' - description: '' type: object example: code: 200 status: success page: domain_id: null url: 'https://example.gov.pl' final_url: 'https://example.gov.pl' code: 200 status: OK content: null content_type: 'text/html; charset=UTF-8' content_size: 15234 content_temp_file: /tmp/crawler_html_abc123 content_archive_file: null links: [] speed: 1.234 error: null ip: 93.184.216.34 score: null screenshot: null client: Laravel/Http type: page dd: content: null raport: null a11y: success: true results: violations: - id: html-has-lang impact: serious tags: - cat.language - wcag2a - wcag311 - ACT description: 'Ensure every HTML document has a lang attribute' help: ' element must have a lang attribute' helpUrl: 'https://dequeuniversity.com/rules/axe/4.10/html-has-lang?application=playwright' nodes: - html: '' target: - html failureSummary: "Fix any of the following:\n The element does not have a lang attribute" - id: image-alt impact: critical tags: - cat.text-alternatives - wcag2a - wcag111 - section508 - ACT description: 'Ensure elements have alternative text or a role of none or presentation' help: 'Images must have alternative text' helpUrl: 'https://dequeuniversity.com/rules/axe/4.10/image-alt?application=playwright' nodes: - html: '' target: - img failureSummary: "Fix any of the following:\n Element does not have an alt attribute" - id: color-contrast impact: serious tags: - cat.color - wcag2aa - wcag143 description: 'Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds' help: 'Elements must meet minimum color contrast ratio thresholds' helpUrl: 'https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=playwright' nodes: - html: 'Kontakt' target: - 'a[href="/contact"]' failureSummary: "Fix any of the following:\n Element has insufficient color contrast of 2.5 (foreground color: #cccccc, background color: #ffffff, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1" url: 'https://example.gov.pl' timestamp: '2025-09-30T18:00:00.000Z' testEngine: name: axe-core version: 4.10.3 ai_analysis: analyzed_violations: - violation_id: html-has-lang human_description: "Strona nie posiada atrybutu 'lang' w elemencie , który informuje przeglądarki i technologie asystujące o języku strony. Użytkownicy korzystający z czytników ekranu mogą mieć problem z poprawnym odczytaniem treści." severity: poważny affected_elements: 1 recommendation: "Dodaj atrybut lang do tagu , np. dla strony w języku polskim. To pomoże czytnikowi ekranu wybrać odpowiednią wymowę i akcent." - violation_id: color-contrast human_description: 'Link ma zbyt niski kontrast między tekstem a tłem (2.5:1), podczas gdy minimum dla WCAG 2.0 AA to 4.5:1. Użytkownicy z problemami ze wzrokiem mogą mieć trudność z odczytaniem tego linku.' severity: poważny affected_elements: 1 recommendation: 'Zmień kolor tekstu z #ccc (jasnoszary) na ciemniejszy, aby osiągnąć kontrast minimum 4.5:1. Możesz użyć narzędzi online do sprawdzenia kontrastu kolorów.' total_analyzed: 2 analysis_timestamp: '2025-09-30T18:05:00.000Z' properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: domain_id: type: string example: null url: type: string example: 'https://example.gov.pl' final_url: type: string example: 'https://example.gov.pl' code: type: integer example: 200 status: type: string example: OK content: type: string example: null content_type: type: string example: 'text/html; charset=UTF-8' content_size: type: integer example: 15234 content_temp_file: type: string example: /tmp/crawler_html_abc123 content_archive_file: type: string example: null links: type: array example: [] speed: type: number example: 1.234 error: type: string example: null ip: type: string example: 93.184.216.34 score: type: string example: null screenshot: type: string example: null client: type: string example: Laravel/Http type: type: string example: page dd: type: object properties: content: type: string example: null raport: type: string example: null a11y: type: object properties: success: type: boolean example: true results: type: object properties: violations: type: array example: - { id: html-has-lang, impact: serious, tags: [cat.language, wcag2a, wcag311, ACT], description: 'Ensure every HTML document has a lang attribute', help: ' element must have a lang attribute', helpUrl: 'https://dequeuniversity.com/rules/axe/4.10/html-has-lang?application=playwright', nodes: [{ html: '', target: [html], failureSummary: "Fix any of the following:\n The element does not have a lang attribute" }] } - { id: image-alt, impact: critical, tags: [cat.text-alternatives, wcag2a, wcag111, section508, ACT], description: 'Ensure elements have alternative text or a role of none or presentation', help: 'Images must have alternative text', helpUrl: 'https://dequeuniversity.com/rules/axe/4.10/image-alt?application=playwright', nodes: [{ html: '', target: [img], failureSummary: "Fix any of the following:\n Element does not have an alt attribute" }] } - { id: color-contrast, impact: serious, tags: [cat.color, wcag2aa, wcag143], description: 'Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds', help: 'Elements must meet minimum color contrast ratio thresholds', helpUrl: 'https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=playwright', nodes: [{ html: 'Kontakt', target: ['a[href="/contact"]'], failureSummary: "Fix any of the following:\n Element has insufficient color contrast of 2.5 (foreground color: #cccccc, background color: #ffffff, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1" }] } items: type: object properties: { id: { type: string, example: html-has-lang }, impact: { type: string, example: serious }, tags: { type: array, example: [cat.language, wcag2a, wcag311, ACT], items: { type: string } }, description: { type: string, example: 'Ensure every HTML document has a lang attribute' }, help: { type: string, example: ' element must have a lang attribute' }, helpUrl: { type: string, example: 'https://dequeuniversity.com/rules/axe/4.10/html-has-lang?application=playwright' }, nodes: { type: array, example: [{ html: '', target: [html], failureSummary: "Fix any of the following:\n The element does not have a lang attribute" }], items: { type: object, properties: { html: { type: string, example: '' }, target: { type: array, example: [html], items: { type: string } }, failureSummary: { type: string, example: "Fix any of the following:\n The element does not have a lang attribute" } } } } } url: type: string example: 'https://example.gov.pl' timestamp: type: string example: '2025-09-30T18:00:00.000Z' testEngine: type: object properties: name: type: string example: axe-core version: type: string example: 4.10.3 ai_analysis: type: object properties: analyzed_violations: type: array example: - { violation_id: html-has-lang, human_description: "Strona nie posiada atrybutu 'lang' w elemencie , który informuje przeglądarki i technologie asystujące o języku strony. Użytkownicy korzystający z czytników ekranu mogą mieć problem z poprawnym odczytaniem treści.", severity: poważny, affected_elements: 1, recommendation: "Dodaj atrybut lang do tagu , np. dla strony w języku polskim. To pomoże czytnikowi ekranu wybrać odpowiednią wymowę i akcent." } - { violation_id: color-contrast, human_description: 'Link ma zbyt niski kontrast między tekstem a tłem (2.5:1), podczas gdy minimum dla WCAG 2.0 AA to 4.5:1. Użytkownicy z problemami ze wzrokiem mogą mieć trudność z odczytaniem tego linku.', severity: poważny, affected_elements: 1, recommendation: 'Zmień kolor tekstu z #ccc (jasnoszary) na ciemniejszy, aby osiągnąć kontrast minimum 4.5:1. Możesz użyć narzędzi online do sprawdzenia kontrastu kolorów.' } items: type: object properties: { violation_id: { type: string, example: html-has-lang }, human_description: { type: string, example: "Strona nie posiada atrybutu 'lang' w elemencie , który informuje przeglądarki i technologie asystujące o języku strony. Użytkownicy korzystający z czytników ekranu mogą mieć problem z poprawnym odczytaniem treści." }, severity: { type: string, example: poważny }, affected_elements: { type: integer, example: 1 }, recommendation: { type: string, example: "Dodaj atrybut lang do tagu , np. dla strony w języku polskim. To pomoże czytnikowi ekranu wybrać odpowiednią wymowę i akcent." } } total_analyzed: type: integer example: 2 analysis_timestamp: type: string example: '2025-09-30T18:05:00.000Z' - description: '' type: object example: code: 200 status: success page: domain_id: null url: 'https://example.gov.pl' final_url: 'https://example.gov.pl' code: 200 status: OK content: null content_type: 'text/html; charset=UTF-8' content_size: 12456 content_temp_file: /tmp/crawler_html_xyz789 content_archive_file: null links: [] speed: 0.987 error: null ip: 93.184.216.34 score: null screenshot: null client: Laravel/Http type: page dd: content: null raport: null a11y: success: true results: violations: [] url: 'https://example.gov.pl' timestamp: '2025-09-30T18:00:00.000Z' testEngine: name: axe-core version: 4.10.3 properties: code: type: integer example: 200 status: type: string example: success page: type: object properties: domain_id: type: string example: null url: type: string example: 'https://example.gov.pl' final_url: type: string example: 'https://example.gov.pl' code: type: integer example: 200 status: type: string example: OK content: type: string example: null content_type: type: string example: 'text/html; charset=UTF-8' content_size: type: integer example: 12456 content_temp_file: type: string example: /tmp/crawler_html_xyz789 content_archive_file: type: string example: null links: type: array example: [] speed: type: number example: 0.987 error: type: string example: null ip: type: string example: 93.184.216.34 score: type: string example: null screenshot: type: string example: null client: type: string example: Laravel/Http type: type: string example: page dd: type: object properties: content: type: string example: null raport: type: string example: null a11y: type: object properties: success: type: boolean example: true results: type: object properties: violations: type: array example: [] url: type: string example: 'https://example.gov.pl' timestamp: type: string example: '2025-09-30T18:00:00.000Z' testEngine: type: object properties: name: type: string example: axe-core version: type: string example: 4.10.3 422: description: 'Błąd walidacji' content: application/json: schema: type: object example: success: false message: 'Validation errors' errors: url: - 'URL jest wymagany' properties: success: type: boolean example: false message: type: string example: 'Validation errors' errors: type: object properties: url: type: array example: - 'URL jest wymagany' items: type: string 500: description: 'Błąd serwera' content: application/json: schema: type: object example: code: 500 status: error message: 'Failed to analyze accessibility' error: 'Playwright not available' properties: code: type: integer example: 500 status: type: string example: error message: type: string example: 'Failed to analyze accessibility' error: type: string example: 'Playwright not available' tags: - 'Crawler API' requestBody: required: true content: application/json: schema: type: object properties: url: type: string description: 'Must be a valid URL. Must match the regex /^https?:\/\//.' example: 'http://' nullable: false domain_id: type: integer description: validation.min. example: 17 nullable: true timeout: type: integer description: 'validation.min validation.max.' example: 23 nullable: true follow_redirects: type: boolean description: '' example: true nullable: true use: type: array description: '' example: - render_js items: type: string enum: - render_js - ai - smart_fetch _: type: integer description: '' example: 18 nullable: true exclude: type: array description: '' example: - content items: type: string enum: - content - links - meta save_to_temp_file: type: boolean description: '' example: true nullable: true type: type: string description: '' example: hp nullable: true enum: - hp - page - link include: type: array description: '' example: - passes items: type: string enum: - violations - passes - incomplete - inapplicable tags: type: array description: '' example: - best-practice items: type: string enum: - wcag2a - wcag2aa - wcag21a - wcag21aa - wcag22aa - best-practice required: - url security: [] /api/collect-links: get: summary: 'Zbieranie linków ze strony (asynchroniczne)' operationId: zbieranieLinkwZeStronyasynchroniczne description: "Endpoint inicjalizuje asynchroniczne zadanie zbierania linków ze strony.\nZwraca job_id i URL do sprawdzania statusu zadania.\n\nCrawler zawsze przechodzi przez wszystkie linki, różnica parametru 'type' polega tylko na tym,\nktóre zasoby są zapisywane do wyników (filtrowanie po Content-Type z HTTP response)." parameters: - in: query name: url description: 'URL strony do skanowania.' example: 'https://example.gov.pl' required: true schema: type: string description: 'URL strony do skanowania.' example: 'https://example.gov.pl' nullable: false - in: query name: max_depth description: 'Głębokość skanowania (1-10). Default: 2.' example: 3 required: false schema: type: integer description: 'Głębokość skanowania (1-10). Default: 2.' example: 3 nullable: false - in: query name: collect description: 'Zakres linków do zebrania: internal (ta sama domena), external (inne domeny), all (wszystkie). Default: internal.' example: external required: false schema: type: string description: 'Zakres linków do zebrania: internal (ta sama domena), external (inne domeny), all (wszystkie). Default: internal.' example: external nullable: false - in: query name: type description: 'Typ zasobów do zapisywania: html (tylko text/*), attachment (tylko załączniki), all (wszystkie). Default: html.' example: attachment required: false schema: type: string description: 'Typ zasobów do zapisywania: html (tylko text/*), attachment (tylko załączniki), all (wszystkie). Default: html.' example: attachment nullable: false - in: query name: max_execution_time description: 'Maksymalny czas wykonania w sekundach (0 = brak limitu). Default: 300.' example: 600 required: false schema: type: integer description: 'Maksymalny czas wykonania w sekundach (0 = brak limitu). Default: 300.' example: 600 nullable: false - in: query name: use description: 'Strategie pobierania: smart_fetch, render_js.' example: - render_js required: false schema: type: array description: 'Strategie pobierania: smart_fetch, render_js.' example: - render_js items: type: string - in: query name: timeout description: 'Timeout pojedynczego requesta w sekundach. Default: 30.' example: 60 required: false schema: type: integer description: 'Timeout pojedynczego requesta w sekundach. Default: 30.' example: 60 nullable: false responses: 200: description: '' content: application/json: schema: type: object example: job_id: abc123def456 status: pending params: url: 'https://example.gov.pl' max_depth: 3 collect: external type: html max_execution_time: 300 use: - render_js timeout: 30 status_url: /api/collect-links/status/abc123def456 created_at: '2025-10-01 10:00:00' properties: job_id: type: string example: abc123def456 status: type: string example: pending params: type: object properties: url: type: string example: 'https://example.gov.pl' max_depth: type: integer example: 3 collect: type: string example: external type: type: string example: html max_execution_time: type: integer example: 300 use: type: array example: - render_js items: type: string timeout: type: integer example: 30 status_url: type: string example: /api/collect-links/status/abc123def456 created_at: type: string example: '2025-10-01 10:00:00' tags: - 'Crawler API' requestBody: required: true content: application/json: schema: type: object properties: url: type: string description: 'Must be a valid URL. Must match the regex /^https?:\/\//.' example: 'https://' nullable: false domain_id: type: integer description: validation.min. example: 20 nullable: true timeout: type: integer description: 'validation.min validation.max.' example: 12 nullable: true follow_redirects: type: boolean description: '' example: false nullable: true use: type: array description: '' example: - ai items: type: string enum: - render_js - ai - smart_fetch _: type: integer description: '' example: 8 nullable: true exclude: type: array description: '' example: - content items: type: string enum: - content - links - meta save_to_temp_file: type: boolean description: '' example: false nullable: true type: type: string description: '' example: all nullable: true enum: - html - attachment - all max_depth: type: integer description: 'validation.min validation.max.' example: 2 nullable: true collect: type: string description: '' example: external nullable: true enum: - internal - external - all max_execution_time: type: integer description: validation.min. example: 15 nullable: true required: - url security: [] '/api/collect-links/status/{jobId}': get: summary: 'Sprawdzanie statusu zadania zbierania linków' operationId: sprawdzanieStatusuZadaniaZbieraniaLinkw description: '' parameters: [] responses: 200: description: '' content: application/json: schema: oneOf: - description: Pending type: object example: job_id: abc123def456 status: pending params: url: 'https://example.gov.pl' max_depth: 3 created_at: '2025-10-01 10:00:00' properties: job_id: type: string example: abc123def456 status: type: string example: pending params: type: object properties: url: type: string example: 'https://example.gov.pl' max_depth: type: integer example: 3 created_at: type: string example: '2025-10-01 10:00:00' - description: Completed type: object example: job_id: abc123def456 status: completed params: url: 'https://example.gov.pl' max_depth: 3 result: total_links: 234 links: - 'https://external.com' - 'https://external2.com' completed_at: '2025-10-01 10:02:15' execution_time: 135.2 properties: job_id: type: string example: abc123def456 status: type: string example: completed params: type: object properties: url: type: string example: 'https://example.gov.pl' max_depth: type: integer example: 3 result: type: object properties: total_links: type: integer example: 234 links: type: array example: - 'https://external.com' - 'https://external2.com' items: type: string completed_at: type: string example: '2025-10-01 10:02:15' execution_time: type: number example: 135.2 - description: Failed type: object example: job_id: abc123def456 status: failed params: url: 'https://example.gov.pl' error: 'Timeout exceeded' failed_at: '2025-10-01 10:05:00' execution_time: 300.0 properties: job_id: type: string example: abc123def456 status: type: string example: failed params: type: object properties: url: type: string example: 'https://example.gov.pl' error: type: string example: 'Timeout exceeded' failed_at: type: string example: '2025-10-01 10:05:00' execution_time: type: number example: 300.0 404: description: '' content: application/json: schema: type: object example: message: 'Job not found' properties: message: type: string example: 'Job not found' tags: - 'Crawler API' security: [] parameters: - in: path name: jobId description: 'ID zadania.' example: abc123def456 required: true schema: type: string /api/jobs: get: summary: 'Lista wszystkich jobów asynchronicznych' operationId: listaWszystkichJobwAsynchronicznych description: "Endpoint zwraca listę wszystkich jobów (collect-links) z możliwością filtrowania po statusie.\nJoby są sortowane po dacie utworzenia (najnowsze pierwsze)." parameters: - in: query name: status description: 'Filtr statusu: pending, completed, failed, all. Default: all.' example: completed required: false schema: type: string description: 'Filtr statusu: pending, completed, failed, all. Default: all.' example: completed nullable: false responses: 200: description: '' content: application/json: schema: oneOf: - description: 'Lista wszystkich jobów' type: object example: total: 156 jobs: - job_id: abc123-def456 status: completed status_url: /api/collect-links/status/abc123-def456 params: url: 'https://wolka.pl' max_depth: 3 collect: external max_execution_time: 300 use: - render_js timeout: 30 created_at: '2025-10-02 09:42:41' completed_at: '2025-10-02 09:42:55' execution_time: 14.2 properties: total: type: integer example: 156 jobs: type: array example: - job_id: abc123-def456 status: completed status_url: /api/collect-links/status/abc123-def456 params: url: 'https://wolka.pl' max_depth: 3 collect: external max_execution_time: 300 use: - render_js timeout: 30 created_at: '2025-10-02 09:42:41' completed_at: '2025-10-02 09:42:55' execution_time: 14.2 items: type: object properties: job_id: type: string example: abc123-def456 status: type: string example: completed status_url: type: string example: /api/collect-links/status/abc123-def456 params: type: object properties: url: type: string example: 'https://wolka.pl' max_depth: type: integer example: 3 collect: type: string example: external max_execution_time: type: integer example: 300 use: type: array example: - render_js items: type: string timeout: type: integer example: 30 created_at: type: string example: '2025-10-02 09:42:41' completed_at: type: string example: '2025-10-02 09:42:55' execution_time: type: number example: 14.2 - description: 'Tylko joby pending' type: object example: total: 3 jobs: - job_id: xyz789 status: pending status_url: /api/collect-links/status/xyz789 params: url: 'https://example.com' max_depth: 2 collect: internal max_execution_time: 300 use: [] timeout: 30 created_at: '2025-10-02 12:30:15' properties: total: type: integer example: 3 jobs: type: array example: - job_id: xyz789 status: pending status_url: /api/collect-links/status/xyz789 params: url: 'https://example.com' max_depth: 2 collect: internal max_execution_time: 300 use: [] timeout: 30 created_at: '2025-10-02 12:30:15' items: type: object properties: job_id: type: string example: xyz789 status: type: string example: pending status_url: type: string example: /api/collect-links/status/xyz789 params: type: object properties: url: type: string example: 'https://example.com' max_depth: type: integer example: 2 collect: type: string example: internal max_execution_time: type: integer example: 300 use: type: array example: [] timeout: type: integer example: 30 created_at: type: string example: '2025-10-02 12:30:15' 422: description: 'Błąd walidacji' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: status: - 'Dozwolone wartości dla status to: pending, completed, failed, all' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: status: type: array example: - 'Dozwolone wartości dla status to: pending, completed, failed, all' items: type: string tags: - 'Crawler API' requestBody: required: false content: application/json: schema: type: object properties: status: type: string description: '' example: pending nullable: true enum: - pending - completed - failed - all security: [] /api/find-samples: get: summary: 'Wyszukiwanie reprezentatywnych próbek stron dla audytu WCAG' operationId: wyszukiwanieReprezentatywnychPrbekStronDlaAudytuWCAG description: "Automatycznie wyszukuje reprezentatywne próbki stron (samples) dla audytu dostępności cyfrowej\nzgodnie z metodologią WCAG-EM. Wykorzystuje AI do inteligentnej identyfikacji typów stron." parameters: - in: query name: url description: 'URL strony głównej do przeszukania.' example: 'https://example.gov.pl' required: true schema: type: string description: 'URL strony głównej do przeszukania.' example: 'https://example.gov.pl' nullable: false - in: query name: sample_types description: 'Typy próbek do wyszukania. Jeśli nie podano, używane są domyślne.' example: - contact_form - article - gallery required: false schema: type: array description: 'Typy próbek do wyszukania. Jeśli nie podano, używane są domyślne.' example: - contact_form - article - gallery items: type: string - in: query name: max_depth description: 'Głębokość przeszukiwania (1-10). Default: 2.' example: 3 required: false schema: type: integer description: 'Głębokość przeszukiwania (1-10). Default: 2.' example: 3 nullable: false - in: query name: max_execution_time description: 'Maksymalny czas wykonania w sekundach (0-1800). Default: 600.' example: 600 required: false schema: type: integer description: 'Maksymalny czas wykonania w sekundach (0-1800). Default: 600.' example: 600 nullable: false - in: query name: timeout description: 'Timeout w sekundach dla pobierania pojedynczej strony (5-120). Default: 30.' example: 30 required: false schema: type: integer description: 'Timeout w sekundach dla pobierania pojedynczej strony (5-120). Default: 30.' example: 30 nullable: false - in: query name: use description: 'Strategie pobierania. Możliwe wartości: render_js, smart_fetch, ai.' example: - ai required: false schema: type: array description: 'Strategie pobierania. Możliwe wartości: render_js, smart_fetch, ai.' example: - ai items: type: string - in: query name: domain_id description: 'ID domeny w systemie.' example: 123 required: false schema: type: integer description: 'ID domeny w systemie.' example: 123 nullable: false responses: 200: description: '' content: application/json: schema: oneOf: - description: 'Job zainicjalizowany' type: object example: code: 200 status: success job_id: 550e8400-e29b-41d4-a716-446655440000 status_url: 'https://api.example.com/api/find-samples/status/550e8400-e29b-41d4-a716-446655440000' params: url: 'https://example.gov.pl' sample_types: - homepage - contact_form - article max_depth: 2 max_execution_time: 600 properties: code: type: integer example: 200 status: type: string example: success job_id: type: string example: 550e8400-e29b-41d4-a716-446655440000 status_url: type: string example: 'https://api.example.com/api/find-samples/status/550e8400-e29b-41d4-a716-446655440000' params: type: object properties: url: type: string example: 'https://example.gov.pl' sample_types: type: array example: - homepage - contact_form - article items: type: string max_depth: type: integer example: 2 max_execution_time: type: integer example: 600 - description: '' type: object example: code: 200 status: success message: 'Job find-samples został utworzony i uruchomiony' job_id: 9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b status_url: /api/find-samples/status/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b data: url: 'https://example.gov.pl' sample_types: - home - contact_form - search - sitemap - login max_depth: 2 max_execution_time: 600 use: - ai - render_js properties: code: type: integer example: 200 status: type: string example: success message: type: string example: 'Job find-samples został utworzony i uruchomiony' job_id: type: string example: 9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b status_url: type: string example: /api/find-samples/status/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b data: type: object properties: url: type: string example: 'https://example.gov.pl' sample_types: type: array example: - home - contact_form - search - sitemap - login items: type: string max_depth: type: integer example: 2 max_execution_time: type: integer example: 600 use: type: array example: - ai - render_js items: type: string 422: description: 'Błąd walidacji' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: sample_types: - 'Nieznany typ próbki' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: sample_types: type: array example: - 'Nieznany typ próbki' items: type: string tags: - 'Crawler API' requestBody: required: true content: application/json: schema: type: object properties: url: type: string description: 'Must be a valid URL. Must match the regex /^https?:\/\//.' example: 'https://' nullable: false domain_id: type: integer description: validation.min. example: 14 nullable: true timeout: type: integer description: 'validation.min validation.max.' example: 13 nullable: true follow_redirects: type: boolean description: '' example: true nullable: true use: type: array description: '' example: - ai items: type: string enum: - smart_fetch - render_js - ai _: type: integer description: '' example: 17 nullable: true exclude: type: array description: '' example: - links items: type: string enum: - content - links - meta save_to_temp_file: type: boolean description: '' example: true nullable: true type: type: string description: '' example: link nullable: true enum: - hp - page - link sample_types: type: array description: '' example: - video_audio items: type: string enum: - homepage - error_page - accessibility_statement - contact_form - login_page - feedback_form - article - news_list - data_table - faq_page - download_page - service_catalog - gallery - video_audio - sitemap - search_page - interactive_elements - calendar_events - location_map - privacy_policy max_depth: type: integer description: 'Głębokość skanowania (1-10).' example: 2 nullable: false max_execution_time: type: integer description: 'Maksymalny czas wykonania w sekundach (0-1800).' example: 600 nullable: false 'use[]': type: array description: "Tablica metod (musi zawierać 'ai')." example: - ai - render_js items: type: string 'sample_types[]': type: array description: 'Typy próbek do wyszukania.' example: - home - contact_form - search items: type: string required: - url - 'use[]' - 'sample_types[]' security: [] '/api/find-samples/status/{jobId}': get: summary: 'Status zadania find-samples' operationId: statusZadaniaFindSamples description: 'Sprawdza status zadania wyszukiwania próbek stron. Zwraca progress i znalezione próbki.' parameters: [] responses: 200: description: '' content: application/json: schema: oneOf: - description: 'Job w trakcie' type: object example: code: 200 status: processing job_id: 550e8400-e29b-41d4-a716-446655440000 progress: total: 10 found: 3 remaining: 7 samples: homepage: url: 'https://example.gov.pl' found: true confidence: high reason: 'Strona główna' contact_form: url: 'https://example.gov.pl/kontakt' found: true confidence: high reason: 'Formularz kontaktowy' article: url: null found: false properties: code: type: integer example: 200 status: type: string example: processing job_id: type: string example: 550e8400-e29b-41d4-a716-446655440000 progress: type: object properties: total: type: integer example: 10 found: type: integer example: 3 remaining: type: integer example: 7 samples: type: object properties: homepage: type: object properties: url: type: string example: 'https://example.gov.pl' found: type: boolean example: true confidence: type: string example: high reason: type: string example: 'Strona główna' contact_form: type: object properties: url: type: string example: 'https://example.gov.pl/kontakt' found: type: boolean example: true confidence: type: string example: high reason: type: string example: 'Formularz kontaktowy' article: type: object properties: url: type: string example: null found: type: boolean example: false - description: 'Job zakończony' type: object example: code: 200 status: completed job_id: 550e8400-e29b-41d4-a716-446655440000 progress: total: 10 found: 8 remaining: 2 samples: { } properties: code: type: integer example: 200 status: type: string example: completed job_id: type: string example: 550e8400-e29b-41d4-a716-446655440000 progress: type: object properties: total: type: integer example: 10 found: type: integer example: 8 remaining: type: integer example: 2 samples: type: object properties: { } - description: '' type: object example: code: 200 status: success job_id: 9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b job_status: completed progress: current: 12 total: 12 percentage: 100 samples: home: found: true url: 'https://example.gov.pl' title: 'Urząd Przykładowy - Strona główna' confidence: high screenshot: /api/find-samples/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b/screenshot/home contact_form: found: true url: 'https://example.gov.pl/kontakt' title: 'Kontakt - Urząd Przykładowy' confidence: high screenshot: /api/find-samples/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b/screenshot/contact_form search: found: true url: 'https://example.gov.pl/wyszukiwarka' title: 'Wyszukiwarka - Urząd Przykładowy' confidence: high screenshot: /api/find-samples/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b/screenshot/search sitemap: found: true url: 'https://example.gov.pl/mapa-strony' title: 'Mapa strony - Urząd Przykładowy' confidence: medium screenshot: /api/find-samples/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b/screenshot/sitemap login: found: false url: null title: null confidence: null screenshot: null stats: found_count: 4 not_found_count: 1 pages_analyzed: 12 execution_time: 45.3 properties: code: type: integer example: 200 status: type: string example: success job_id: type: string example: 9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b job_status: type: string example: completed progress: type: object properties: current: type: integer example: 12 total: type: integer example: 12 percentage: type: integer example: 100 samples: type: object properties: home: type: object properties: found: type: boolean example: true url: type: string example: 'https://example.gov.pl' title: type: string example: 'Urząd Przykładowy - Strona główna' confidence: type: string example: high screenshot: type: string example: /api/find-samples/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b/screenshot/home contact_form: type: object properties: found: type: boolean example: true url: type: string example: 'https://example.gov.pl/kontakt' title: type: string example: 'Kontakt - Urząd Przykładowy' confidence: type: string example: high screenshot: type: string example: /api/find-samples/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b/screenshot/contact_form search: type: object properties: found: type: boolean example: true url: type: string example: 'https://example.gov.pl/wyszukiwarka' title: type: string example: 'Wyszukiwarka - Urząd Przykładowy' confidence: type: string example: high screenshot: type: string example: /api/find-samples/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b/screenshot/search sitemap: type: object properties: found: type: boolean example: true url: type: string example: 'https://example.gov.pl/mapa-strony' title: type: string example: 'Mapa strony - Urząd Przykładowy' confidence: type: string example: medium screenshot: type: string example: /api/find-samples/9d4e8c2a-1b3f-4d5e-8f9a-2c3d4e5f6a7b/screenshot/sitemap login: type: object properties: found: type: boolean example: false url: type: string example: null title: type: string example: null confidence: type: string example: null screenshot: type: string example: null stats: type: object properties: found_count: type: integer example: 4 not_found_count: type: integer example: 1 pages_analyzed: type: integer example: 12 execution_time: type: number example: 45.3 404: description: 'Job nie znaleziony' content: application/json: schema: type: object example: code: 404 status: error message: 'Job not found' properties: code: type: integer example: 404 status: type: string example: error message: type: string example: 'Job not found' tags: - 'Crawler API' security: [] parameters: - in: path name: jobId description: '' example: sed required: true schema: type: string - in: path name: job_id description: 'UUID zadania.' example: 550e8400-e29b-41d4-a716-446655440000 required: true schema: type: string '/api/find-samples/{jobId}/screenshot/{sampleType}': get: summary: 'Pobierz screenshot próbki' operationId: pobierzScreenshotPrbki description: "Zwraca plik PNG ze screenshotem znalezionej próbki.\nEndpoint publiczny - nie wymaga autentykacji (job_id = UUID, trudny do zgadnięcia)." parameters: [] responses: 200: description: 'Screenshot znaleziony' content: text/plain: schema: type: string example: '[binary PNG file]' 404: description: 'Screenshot nie istnieje' content: application/json: schema: type: object example: code: 404 status: error message: 'Screenshot not found' properties: code: type: integer example: 404 status: type: string example: error message: type: string example: 'Screenshot not found' tags: - 'Crawler API' security: [] parameters: - in: path name: jobId description: '' example: in required: true schema: type: string - in: path name: sampleType description: '' example: consequatur required: true schema: type: string - in: path name: job_id description: 'UUID joba.' example: 9d4e8c72-1234-5678-9abc-def012345678 required: true schema: type: string - in: path name: sample_type description: 'Typ próbki (homepage, contact_form, etc.).' example: contact_form required: true schema: type: string /api/sample-types: get: summary: 'Pobierz dostępne typy próbek z konfiguracji' operationId: pobierzDostpneTypyPrbekZKonfiguracji description: '' parameters: [] responses: 404: description: '' content: application/json: schema: type: object example: message: 'The route api/sample-types could not be found.' properties: message: type: string example: 'The route api/sample-types could not be found.' tags: - 'Crawler API' security: [] /api/a11y-fastscan: get: summary: 'A11Y FASTSCAN - Comprehensive accessibility audit' operationId: a11YFASTSCANComprehensiveAccessibilityAudit description: "Comprehensive accessibility audit combining:\n1. find-samples - finding representative page samples\n2. scan-accessibility - axe-core analysis per sample\n3. AI aggregate - violations aggregation + change scale assessment" parameters: - in: query name: url description: 'Starting URL (usually homepage).' example: 'https://wolka.pl' required: true schema: type: string description: 'Starting URL (usually homepage).' example: 'https://wolka.pl' nullable: false - in: query name: 'use[]' description: 'Methods: render_js (Playwright + screenshots), ai (AI analysis).' example: null required: false schema: type: array description: 'Methods: render_js (Playwright + screenshots), ai (AI analysis).' example: null items: type: string - in: query name: 'sample_types[]' description: 'Sample types to scan (default: 8 key types).' example: null required: false schema: type: array description: 'Sample types to scan (default: 8 key types).' example: null items: type: string - in: query name: max_depth description: 'Crawling depth for find-samples (1-10).' example: 3 required: false schema: type: integer description: 'Crawling depth for find-samples (1-10).' example: 3 nullable: false - in: query name: max_execution_time description: 'Max execution time in seconds (0-1800).' example: 600 required: false schema: type: integer description: 'Max execution time in seconds (0-1800).' example: 600 nullable: false - in: query name: timeout description: 'Timeout per page in seconds.' example: 30 required: false schema: type: integer description: 'Timeout per page in seconds.' example: 30 nullable: false - in: query name: domain_id description: 'Domain ID for archiving.' example: 1 required: false schema: type: integer description: 'Domain ID for archiving.' example: 1 nullable: false responses: 200: description: '' content: application/json: schema: oneOf: - description: 'Job created' type: object example: code: 200 status: success job_id: 550e8400-e29b-41d4-a716-446655440000 status_url: 'https://crawler.deklaracja-dostepnosci.info/api/a11y-fastscan/status/550e8400-e29b-41d4-a716-446655440000' properties: code: type: integer example: 200 status: type: string example: success job_id: type: string example: 550e8400-e29b-41d4-a716-446655440000 status_url: type: string example: 'https://crawler.deklaracja-dostepnosci.info/api/a11y-fastscan/status/550e8400-e29b-41d4-a716-446655440000' - description: '' type: object example: code: 200 status: success job_id: 550e8400-e29b-41d4-a716-446655440000 status_url: 'https://crawler.deklaracja-dostepnosci.info/api/a11y-fastscan/status/550e8400-e29b-41d4-a716-446655440000' message: 'Audyt dostępności został zainicjowany. Użyj status_url aby monitorować postęp.' properties: code: type: integer example: 200 status: type: string example: success job_id: type: string example: 550e8400-e29b-41d4-a716-446655440000 status_url: type: string example: 'https://crawler.deklaracja-dostepnosci.info/api/a11y-fastscan/status/550e8400-e29b-41d4-a716-446655440000' message: type: string example: 'Audyt dostępności został zainicjowany. Użyj status_url aby monitorować postęp.' 422: description: 'Validation error' content: application/json: schema: type: object example: code: 422 status: error message: 'Invalid parameters' errors: url: - 'The url field is required.' properties: code: type: integer example: 422 status: type: string example: error message: type: string example: 'Invalid parameters' errors: type: object properties: url: type: array example: - 'The url field is required.' items: type: string tags: - 'A11Y FastScan' requestBody: required: true content: application/json: schema: type: object properties: url: type: string description: 'Adres startowy strony do audytu.' example: 'https://wolka.pl' nullable: false domain_id: type: integer description: 'ID domeny dla archiwizacji.' example: 1 nullable: true timeout: type: integer description: 'Timeout per strona w sekundach.' example: 30 nullable: true follow_redirects: type: boolean description: '' example: true nullable: true use: type: array description: '' example: - smart_fetch items: type: string enum: - render_js - ai - smart_fetch _: type: integer description: '' example: 18 nullable: true sample_types: type: array description: '' example: - article items: type: string enum: - homepage - error_page - accessibility_statement - contact_form - login_page - feedback_form - article - news_list - data_table - faq_page - download_page - service_catalog - gallery - video_audio - sitemap - search_page - interactive_elements - calendar_events - location_map - privacy_policy max_depth: type: integer description: 'Głębokość crawlingu dla find-samples (1-10).' example: 3 nullable: true max_execution_time: type: integer description: 'Maksymalny czas wykonania całego audytu w sekundach (0-1800).' example: 600 nullable: true 'use[]': type: array description: 'Metody skanowania: render_js (Playwright + screenshoty), ai (analiza AI).' example: - ai - render_js items: type: string 'sample_types[]': type: array description: 'Typy próbek do skanowania (domyślnie: 8 kluczowych).' example: - homepage - contact_form - article items: type: string required: - url security: [] '/api/a11y-fastscan/status/{jobId}': get: summary: 'Get a11y-fastscan job status with partial/full report' operationId: getA11yFastscanJobStatusWithPartialfullReport description: '' parameters: [] responses: 200: description: '' content: application/json: schema: oneOf: - description: 'Job completed' type: object example: code: 200 status: completed job_id: 550e8400-e29b-41d4-a716-446655440000 progress: phase: completed current_step: 4 total_steps: 4 percentage: 100 report: summary: { } violations_by_type: [] pages_analyzed: [] properties: code: type: integer example: 200 status: type: string example: completed job_id: type: string example: 550e8400-e29b-41d4-a716-446655440000 progress: type: object properties: phase: type: string example: completed current_step: type: integer example: 4 total_steps: type: integer example: 4 percentage: type: integer example: 100 report: type: object properties: summary: type: object properties: { } violations_by_type: type: array example: [] pages_analyzed: type: array example: [] - description: 'Job processing' type: object example: code: 200 status: processing job_id: 550e8400-e29b-41d4-a716-446655440000 progress: phase: scanning_samples current_step: 2 total_steps: 4 percentage: 50 current_sample: 3 total_samples: 8 properties: code: type: integer example: 200 status: type: string example: processing job_id: type: string example: 550e8400-e29b-41d4-a716-446655440000 progress: type: object properties: phase: type: string example: scanning_samples current_step: type: integer example: 2 total_steps: type: integer example: 4 percentage: type: integer example: 50 current_sample: type: integer example: 3 total_samples: type: integer example: 8 - description: 'Job processing' type: object example: code: 200 status: processing job_id: 550e8400-e29b-41d4-a716-446655440000 progress: phase: scanning_samples current_step: 2 total_steps: 4 percentage: 50 current_sample: 3 total_samples: 8 sample_type: contact_form sample_url: 'https://example.com/kontakt' message: 'Audyt w trakcie realizacji. Aktualna faza: skanowanie próbek.' properties: code: type: integer example: 200 status: type: string example: processing job_id: type: string example: 550e8400-e29b-41d4-a716-446655440000 progress: type: object properties: phase: type: string example: scanning_samples current_step: type: integer example: 2 total_steps: type: integer example: 4 percentage: type: integer example: 50 current_sample: type: integer example: 3 total_samples: type: integer example: 8 sample_type: type: string example: contact_form sample_url: type: string example: 'https://example.com/kontakt' message: type: string example: 'Audyt w trakcie realizacji. Aktualna faza: skanowanie próbek.' - description: 'Job completed' type: object example: code: 200 status: completed job_id: 550e8400-e29b-41d4-a716-446655440000 progress: phase: completed current_step: 4 total_steps: 4 percentage: 100 report: summary: total_pages_scanned: 8 pages_with_violations: 7 total_violations: 45 unique_violation_types: 12 severity_distribution: critical: 3 serious: 15 moderate: 20 minor: 7 change_scale: moderate estimated_effort: 'Umiarkowany - wymagane zmiany w HTML i stylach CSS. Część problemów można rozwiązać globalnie poprzez aktualizację stylów, inne wymagają modyfikacji struktury formularzy i nawigacji.' violations_by_type: - violation_id: color-contrast priority: HIGH severity: serious total_occurrences: 12 pages_affected: - 'https://example.com/' - 'https://example.com/kontakt' - 'https://example.com/aktualnosci' - 'https://example.com/uslugi' - 'https://example.com/o-nas' - 'https://example.com/galeria' is_systemic: true sample_types_affected: - homepage - contact_form - article - gallery - accessibility_statement - search_form description: 'Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds' help: 'Elements must meet minimum color contrast ratio thresholds' help_url: 'https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=playwright' human_description: 'Zbyt niski kontrast między tekstem a tłem utrudnia czytanie treści, szczególnie osobom z problemami ze wzrokiem. Problem występuje w wielu miejscach na stronie, głównie w nawigacji głównej i stopce.' recommendation: 'Zmień kolory w globalnych stylach CSS tak, aby kontrast między tekstem a tłem wynosił co najmniej 4.5:1 dla normalnego tekstu i 3:1 dla dużego tekstu (18px bold lub 24px+). Sprawdź kolory za pomocą narzędzia kontrastu WCAG.' fix_effort: minor - violation_id: label priority: HIGH severity: serious total_occurrences: 8 pages_affected: - 'https://example.com/kontakt' - 'https://example.com/szukaj' is_systemic: false sample_types_affected: - contact_form - search_form description: 'Ensure every form element has a label' help: 'Form elements must have labels' help_url: 'https://dequeuniversity.com/rules/axe/4.10/label?application=playwright' human_description: 'Pola formularzy nie mają etykiet