{"components":{"securitySchemes":{"AdminApiKey":{"description":"Administrator API key with elevated permissions.\nOnly a handful of users have access to this type of key.\nContact support@webperf.se to apply for access - web agencies only.","in":"header","name":"api-key","type":"apiKey"},"ApiKeyAuth":{"description":"Standard API key for premium users","in":"header","name":"api-key","type":"apiKey"},"QueryApiKey":{"description":"API key sent as a query parameter (for backwards compatibility)","in":"query","name":"api-key","type":"apiKey"}}},"info":{"description":"API for webperf.se - provides open data on the web performance of Swedish public sector websites, plus premium features for analysis and testing.","title":"api.webperf.se","version":"1.0.0","x-generated-from":"openapi.json"},"openapi":"3.0.0","paths":{"/0.1/private_stats/{siteId}":{"get":{"description":"Fetches the latest private test results for a specific website","operationId":"getPrivateStats","parameters":[{"description":"The website's id number","example":3843,"in":"path","name":"siteId","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: latest private results","tags":["premium"]}},"/0.1/stats/":{"get":{"description":"Fetches statistics for every website you have access to","operationId":"getAllStats","responses":{"200":{"content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: list all websites","tags":["premium"]}},"/0.1/stats/{siteId}":{"get":{"description":"Fetches the latest test results for a specific website","operationId":"getStats","parameters":[{"description":"The website's id number","example":3843,"in":"path","name":"siteId","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: latest results","tags":["premium"]}},"/0.1/stats_per_month/{siteId}":{"get":{"description":"Fetches historical test results grouped by month","operationId":"getStatsPerMonth","parameters":[{"description":"The website's id number","example":3843,"in":"path","name":"siteId","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: historical results","tags":["premium"]}},"/0.1/test_once/":{"post":{"description":"Runs a one-off test of up to 10 pages of your choice, on the website's own domain. Each page tested costs 15 credits from the rolling 30-day quota, the same price as in the web interface at webperf.cloud. If the whole order does not fit, it is refused. The results are private and reached via /private_stats/.","operationId":"testOnce","parameters":[{"description":"The website's id number","example":3843,"in":"header","name":"site-id","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"urls":{"description":"Comma-separated list of URLs to test","example":"https://webperf.se/events/ndc-oslo/, https://webperf.se/events/?typ=Intran\u00e4t","type":"string"}},"required":["urls"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: one-off test","tags":["premium"]}},"/audit/":{"post":{"description":"Orders an audit of the website. The audit always starts from the website's own start page and crawls its way to the pages it tests - you cannot submit a URL list of your own. The page count in pages decides how many pages are crawled, and costs 1 credit per page from your rolling 30-day quota.","operationId":"createAudit","parameters":[{"description":"The website's id number","example":3843,"in":"header","name":"site-id","required":true,"schema":{"type":"integer"}},{"description":"Number of pages to crawl and test. Costs 1 credit per page. Can also be sent as form-data under the same name.","example":50,"in":"header","name":"pages","required":true,"schema":{"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"400":{"description":"Bad request - pages is missing or less than 1, there are not enough credits for the order, or content was sent along (no longer supported)"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"},"429":{"description":"Too many requests - at most one audit order per hour"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: new audit","tags":["premium"]}},"/audit_file/":{"get":{"description":"Fetches a single report file listed in result_files from /audits/. The files sit outside the web root and are not publicly readable: every call requires api-key + site-id, and the folder must belong to the website in site-id. Allowed file names are accessibility_summary.json, performance_summary.json, seo_summary.json, best-practices_summary.json and - for format audit_v2 - crux_summary.json, privacy_summary.json and summaries.zip.","operationId":"getAuditFile","parameters":[{"description":"The website's id number","example":3843,"in":"header","name":"site-id","required":true,"schema":{"type":"integer"}},{"description":"The report folder's name, from folder in the audit row's content","example":"webbplats.se_20260804_133339-summary_reports","in":"query","name":"folder","required":true,"schema":{"type":"string"}},{"description":"File name from result_files","example":"seo_summary.json","in":"query","name":"file","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}},"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"The report file"},"400":{"description":"api-key/site-id, folder or file is missing"},"403":{"description":"The key has no access to the website, or the folder belongs to another website"},"404":{"description":"Unknown file name, or the file does not exist"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: fetch a report file from an audit","tags":["premium"]},"post":{"description":"Fetches a single report file listed in result_files from /audits/. The files sit outside the web root and are not publicly readable: every call requires api-key + site-id, and the folder must belong to the website in site-id. Allowed file names are accessibility_summary.json, performance_summary.json, seo_summary.json, best-practices_summary.json and - for format audit_v2 - crux_summary.json, privacy_summary.json and summaries.zip.","operationId":"postAuditFile","parameters":[{"description":"The website's id number","example":3843,"in":"header","name":"site-id","required":true,"schema":{"type":"integer"}},{"description":"The report folder's name, from folder in the audit row's content","example":"webbplats.se_20260804_133339-summary_reports","in":"query","name":"folder","required":true,"schema":{"type":"string"}},{"description":"File name from result_files","example":"seo_summary.json","in":"query","name":"file","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}},"application/zip":{"schema":{"format":"binary","type":"string"}}},"description":"The report file"},"400":{"description":"api-key/site-id, folder or file is missing"},"403":{"description":"The key has no access to the website, or the folder belongs to another website"},"404":{"description":"Unknown file name, or the file does not exist"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: fetch a report file from an audit","tags":["premium"]}},"/audits/":{"post":{"description":"Lists every audit for a website. Each row has site_id (the website's id), result_id (the row's own id), format (csv, audit or audit_v2) and result_files - URLs to /audit_file/ that require the same api-key + site-id. Rows with format csv have no result_files; audit_v2 has two more files than audit, plus summaries.zip.","operationId":"listAudits","parameters":[{"description":"The website's id number","example":3843,"in":"header","name":"site-id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: list audits","tags":["premium"]}},"/categories/":{"get":{"description":"Lists all available categories","operationId":"getCategories","responses":{"200":{"content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: fetch categories","tags":["premium"]}},"/health":{"get":{"description":"Status of the API and its database connection. Responds 503 if something is wrong.","operationId":"getHealth","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"503":{"description":"Service unavailable - the database is not responding"}},"summary":"Health check","tags":["opendata"]}},"/info":{"get":{"description":"Name, version, environment and a list of available endpoints. No key required. Also available at /api/info.","operationId":"getInfo","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"}},"summary":"API information","tags":["opendata"]}},"/item/{id}":{"get":{"description":"Fetches information about a specific website by its id","operationId":"getItem","parameters":[{"description":"The website's id number","example":141,"in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"}},"summary":"A single website","tags":["opendata"]}},"/openapi.json":{"get":{"description":"This specification in JSON. Generated from openapi.yml.","operationId":"getOpenApiJson","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"}},"summary":"OpenAPI specification (JSON)","tags":["opendata"]}},"/openapi.yaml":{"get":{"description":"This specification in YAML. Also available at /openapi.yml.","operationId":"getOpenApiYaml","responses":{"200":{"content":{"application/x-yaml":{"schema":{"type":"string"}}},"description":"Successful response"}},"summary":"OpenAPI specification (YAML)","tags":["opendata"]}},"/private_stats/{siteId}/{testId}":{"get":{"description":"Fetches one specific private test result","operationId":"getPrivateTestResult","parameters":[{"description":"The website's id number","example":3843,"in":"path","name":"siteId","required":true,"schema":{"type":"integer"}},{"description":"The test's id number","example":6616,"in":"path","name":"testId","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: a single private test result","tags":["premium"]}},"/public-sector/":{"get":{"description":"Fetches information about the web performance of every Swedish municipality and region","operationId":"getPublicSector","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"}},"summary":"All municipalities and regions","tags":["opendata"]}},"/quota/":{"get":{"description":"The credit account for a website in the rolling 30-day period. The quota is either set on the website itself or derived from its premium level. Orders cost 1 credit per test in a re-test, 15 credits per privately tested page and 1 credit per page audited, so this endpoint is what tells you whether the next order fits. Every number is an integer; no account type has an unlimited quota, and a website with no premium level gets 0 and cannot order anything.","operationId":"getQuota","parameters":[{"description":"The website's id number","example":3843,"in":"header","name":"site-id","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"available":{"description":"Remaining credits, never below 0","type":"integer"},"effective_limit":{"description":"The same ceiling; kept for backwards compatibility","type":"integer"},"monthly_quota":{"description":"The website's ceiling for the period","type":"integer"},"period_days":{"description":"The length of the rolling window (30)","type":"integer"},"site_id":{"description":"The website's id number","type":"integer"},"used":{"description":"Credits used over the last 30 days","type":"integer"}},"type":"object"}}},"description":"Successful response"},"400":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"},"404":{"description":"Not found - the website does not exist"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: remaining credits","tags":["premium"]}},"/retest/":{"post":{"description":"Re-runs specific tests for a website","operationId":"retest","parameters":[{"description":"The website's id number","example":3843,"in":"header","name":"site-id","required":true,"schema":{"type":"integer"}},{"description":"Array of test numbers to re-run","example":"[10,15]","in":"header","name":"testnums","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: re-test","tags":["premium"]}},"/swagger":{"get":{"description":"Interactive documentation where endpoints can be tried out in the browser. Also available at /docs and /v1/docs.","operationId":"getSwaggerUi","responses":{"200":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"Successful response"}},"summary":"Swagger UI","tags":["opendata"]}},"/tools/lix/":{"post":{"description":"Analyses a text and calculates its LIX value (readability index)","operationId":"calculateLix","parameters":[{"description":"The website's id number","example":3843,"in":"header","name":"site-id","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"content":{"description":"Text to analyse for a LIX value","example":"Enter your text here for LIX analysis","type":"string"}},"required":["content"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"lix":{"description":"The calculated LIX value","type":"number"}},"type":"object"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - insufficient permissions"}},"security":[{"ApiKeyAuth":[]}],"summary":"Premium: calculate LIX","tags":["premium"]}},"/v1/tests":{"get":{"description":"Authoritative catalogue of every Webperf Core test type with its\ncanonical numeric id and localised name. Names of currently-active\ntests come verbatim from Webperf Core's own locale files; descriptions\nand historical-test names in Danish/Norwegian/Finnish/Icelandic are\nmachine-translated from the Swedish/English source.\n\nStatic reference data \u2014 served with a long `Cache-Control` and an\n`ETag`, so conditional `If-None-Match` requests get `304 Not Modified`.\n","parameters":[{"description":"Flatten the response to a single language. Omit for all languages.","example":"sv","in":"query","name":"lang","required":false,"schema":{"enum":["sv","en","da","no","fi","is"],"type":"string"}},{"description":"When truthy (1/true/yes), return only currently-active tests.","example":"true","in":"query","name":"active","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"},"meta":{"type":"object"},"tests":{"items":{"$ref":"#/components/schemas/TestType"},"type":"array"}},"type":"object"}}},"description":"List of test types"},"304":{"description":"Not Modified (ETag matched)"},"400":{"description":"Unsupported language"}},"summary":"Webperf Core test types (authoritative names, all Nordic languages + English)","tags":["opendata"]}},"/v1/tests/{test_id}":{"get":{"parameters":[{"example":15,"in":"path","name":"test_id","required":true,"schema":{"type":"integer"}},{"example":"sv","in":"query","name":"lang","required":false,"schema":{"enum":["sv","en","da","no","fi","is"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"meta":{"type":"object"},"test":{"$ref":"#/components/schemas/TestType"}},"type":"object"}}},"description":"A single test type"},"304":{"description":"Not Modified (ETag matched)"},"400":{"description":"Unsupported language"},"404":{"description":"Unknown test id"}},"summary":"A single Webperf Core test type by numeric id","tags":["opendata"]}},"/webanalytics":{"get":{"description":"**\u26a0\ufe0f RESTRICTED ACCESS**\nThis endpoint requires a special administrator API key.\nOnly available to administrators and web agencies.","operationId":"getWebAnalytics","responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Successful response"},"401":{"description":"Unauthorized - API key missing or invalid"},"403":{"description":"Forbidden - administrator permissions required"}},"security":[{"QueryApiKey":[]}],"summary":"Premium: web analytics statistics","tags":["premium","admin-only"],"x-access-note":"Only available to admins and web agencies","x-permission-level":"admin"}}},"servers":[{"description":"Production server","url":"https://api.webperf.se"}],"tags":[{"description":"Open APIs, no authentication required","name":"opendata"},{"description":"Premium APIs that require an API key","name":"premium"},{"description":"APIs that require administrator permissions","name":"admin-only"}]}
