API overview
A JSON API over HTTPS that does everything the dashboard does.
The API gives you everything the dashboard does: analyse a page, read the findings, run a site crawl, watch a URL for downtime. It is a plain JSON API over HTTPS, and anything you can do with it you could also do by hand, which makes it easy to check your work against the interface.
What you need
An API key, and a plan that includes API access. Pro and Agency do; Free and Basic do not, and a key on those plans is refused with a message saying so rather than silently returning nothing.
Keys are created in the dashboard under Plan and usage → API keys. A key belongs to one workspace and spends that account's monthly allowance.
Base URL
Every endpoint sits under one prefix, and the version is part of it:
https://webrankpage.com/api/v1The version changes only when a response shape changes in a way that would break something reading it. Adding a field is not a breaking change, so parse defensively and ignore what you do not recognise.
A first call
/me is the endpoint to try first. It takes no parameters,
changes nothing, and tells you which workspace your key reaches and what
the plan allows:
curl "https://webrankpage.com/api/v1/me" \
-H "Authorization: Bearer wrp_live_8fKp2mQx9tR4vN7c"<?php
$ch = curl_init('https://webrankpage.com/api/v1/me');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer wrp_live_8fKp2mQx9tR4vN7c'],
]);
print_r(json_decode(curl_exec($ch), true));// Server-side only. A key in browser code is readable by anyone.
const res = await fetch('https://webrankpage.com/api/v1/me', {
headers: { Authorization: `Bearer ${process.env.WEBRANKPAGE_KEY}` },
});
console.log(await res.json());import requests
res = requests.get(
'https://webrankpage.com/api/v1/me',
headers={'Authorization': 'Bearer wrp_live_8fKp2mQx9tR4vN7c'},
)
print(res.json())require 'net/http'
require 'json'
uri = URI('https://webrankpage.com/api/v1/me')
req = Net::HTTP::Get.new(uri)
req['Authorization'] = 'Bearer wrp_live_8fKp2mQx9tR4vN7c'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
puts JSON.parse(res.body)package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://webrankpage.com/api/v1/me", nil)
req.Header.Set("Authorization", "Bearer wrp_live_8fKp2mQx9tR4vN7c")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]interface{}
json.NewDecoder(res.Body).Decode(&data)
fmt.Println(data)
}A successful call returns:
{
"key": {
"name": "docs-temp",
"prefix": "wrp_7Hzu7VRo"
},
"workspace": {
"id": 172,
"slug": "your-pages",
"name": "Your pages"
},
"plan": {
"name": "Agency",
"site_crawl": true,
"uptime": true
}
}Conventions
| How it works | |
|---|---|
| Format | JSON in, JSON out. Send Content-Type: application/json on anything with a body. |
| Methods | GET reads, POST creates, DELETE removes. Nothing uses PUT or PATCH. |
| Dates | ISO 8601 with an offset, always UTC: 2026-09-24T11:53:49+00:00. |
| Paging | limit and offset on list endpoints. The default limit is 25 and the maximum is 100. |
| Errors | A non-2xx status and a body with error.code and error.message. See Errors. |
Rate limits
A key may make 60 calls a minute. The ceiling is per key rather than
per account, so a runaway loop in one integration cannot starve the others
beside it. Going over returns 429 with a
retry_after of 60 seconds.
Separately, every call counts against your plan's monthly API allowance, and an analysis counts against your monthly report allowance as well. GET /usage reports both.
Every response shown in this reference was captured from the live API rather than written by hand, so what you see is what the server sends.