One rank tracking API with an OpenAPI spec, a CLI and SDKs for TypeScript, Python and Go. Run rank checks and read history from code.
Then create an API key in Settings / Developers
Paid calls run on your own DataForSEO or SerpApi account · Estimates are free · Self-host (AGPL-3.0)
POST /api/v1/keywords/{id}/checks
export BISIBILITY_BASE_URL=https://eu.bisibility.com/api/v1curl -sS -X POST \ "$BISIBILITY_BASE_URL/keywords/kw_a00000000000000000000000/checks" \ -H "Authorization: Bearer $BISIBILITY_API_KEY" \ -H "Idempotency-Key: run-check-001" \ -H "Content-Type: application/json" \ -d '{"max_cost_cents": 1}' \ | jq '{position, previous_position, ranking_url, cost_cents}'{ "position": 4, "previous_position": 7, "ranking_url": "https://example.com/rank-tracker", "cost_cents": 0.06}201 when the check finishes during the request; 202 with a run ID when it is queued.
npm install @bisibility/sdk
import { BisibilityClient } from "@bisibility/sdk";const bisibility = new BisibilityClient({ apiKey: process.env.BISIBILITY_API_KEY, baseUrl: "https://eu.bisibility.com/api/v1",});const check = await bisibility.rankChecks.runAndWait("kw_a00000000000000000000000");console.log(check.position, check.previous_position, check.ranking_url, check.cost_cents);4 7 https://example.com/rank-tracker 0.06pip install bisibility
import osfrom bisibility import BisibilityClientbisibility = BisibilityClient( api_key=os.environ["BISIBILITY_API_KEY"], base_url="https://eu.bisibility.com/api/v1",)check = bisibility.run_rank_check_and_wait("kw_a00000000000000000000000")print(check.position, check.previous_position, check.ranking_url, check.cost_cents)4 7 https://example.com/rank-tracker 0.06go get bisibility.com/sdk-go
// inside main(), with ctx := context.Background()client, err := bisibility.NewClient( bisibility.WithAPIKey(os.Getenv("BISIBILITY_API_KEY")), bisibility.WithBaseURL("https://eu.bisibility.com/api/v1"),)if err != nil { log.Fatal(err)}check, err := client.RunRankCheckAndWait(ctx, "kw_a00000000000000000000000", nil, nil)if err != nil { log.Fatal(err)}if check.Position != nil && check.RankingURL != nil { fmt.Println(*check.Position, *check.RankingURL)}4 https://example.com/rank-trackernpm install -g @bisibility/cli
bisibility auth loginbisibility check kw_a00000000000000000000000check check_a00000000000000000000000keyword kw_a00000000000000000000000status completedposition 4previous 7provider dataforseourl https://example.com/rank-trackererror -REST API
Every REST operation the SDKs and CLI use is a plain HTTPS call in a public OpenAPI 3.1 document.
Keys for the bisibility API, each with a scope and an expiry.
created Sep 20, 2026, 11:44 PM · last used Sep 28, 2026, 2:17 AM
Spend this month: $0.42
created Sep 22, 2026, 8:44 AM · last used never
Spend this month: $0.00
Provider budgets
Set a monthly budget for each provider. Using the provider balance includes this month's usage so the remaining budget matches the available balance.
When a budget is reached, the requests of that surface stop until next month; the other surface keeps running.
SDKs and CLI
Three official SDKs provide typed requests and responses. The CLI runs checks, research and exports from your terminal or CI job.
npm install @bisibility/sdkimport { BisibilityClient } from "@bisibility/sdk";const bisibility = new BisibilityClient({ apiKey: process.env.BISIBILITY_API_KEY, baseUrl: "https://eu.bisibility.com/api/v1",});const check = await bisibility.rankChecks.runAndWait("kw_a00000000000000000000000");console.log(check.position, check.previous_position, check.ranking_url, check.cost_cents);Runtime Node 18+Wait helper rankChecks.runAndWaitpip install bisibilityimport osfrom bisibility import BisibilityClientbisibility = BisibilityClient( api_key=os.environ["BISIBILITY_API_KEY"], base_url="https://eu.bisibility.com/api/v1",)check = bisibility.run_rank_check_and_wait("kw_a00000000000000000000000")print(check.position, check.previous_position, check.ranking_url, check.cost_cents)Runtime Python 3.10+Wait helper run_rank_check_and_waitgo get bisibility.com/sdk-go// inside main(), with ctx := context.Background()client, err := bisibility.NewClient( bisibility.WithAPIKey(os.Getenv("BISIBILITY_API_KEY")), bisibility.WithBaseURL("https://eu.bisibility.com/api/v1"),)if err != nil { log.Fatal(err)}check, err := client.RunRankCheckAndWait(ctx, "kw_a00000000000000000000000", nil, nil)if err != nil { log.Fatal(err)}if check.Position != nil && check.RankingURL != nil { fmt.Println(*check.Position, *check.RankingURL)}Runtime Go 1.22Wait helper RunRankCheckAndWaitnpm install -g @bisibility/cli# sign in once (opens the browser)bisibility auth loginbisibility projects use example.com# price a backlinks lookup, then run it with a 7-cent capbisibility backlinks analyze example.com --estimatebisibility backlinks analyze example.com --limit 100 --max-cost 7Webhooks
Alert rules post to up to 10 HTTPS endpoints per project. Deploys flow the other way, from your CI into bisibility.
POST https://example.com/hooks/bisibilityX-Bisibility-Timestamp: 1784980803X-Bisibility-Signature: sha256=4f1c…e9a2{ "event": "alert.fired", "schemaVersion": 3, "created_at": "2026-07-25T12:00:03.000Z", "data": { "headline": "Rank tracker dropped from #4 to #11", "keyword": "rank tracker", "before_position": 4, "after_position": 11, "condition_type": "position_drop", "rule_name": "Important position drops", "project_domain": "example.com", "keyword_id": "kw_a00000000000000000000000" }}Self-host
The app is open source under AGPL-3.0, and the CLI and SDKs are Apache-2.0. A self-hosted instance serves the same API from its own origin.
# Cloud (EU region)bisibility config set baseUrl https://eu.bisibility.com/api/v1# Your serverbisibility config set baseUrl https://rank.example.com/api/v1bisibility config set cloudUrl https://rank.example.combisibility auth loginbisibility export --format json --output dump.jsonNo. bisibility does not scrape Google or bundle SERP data. Calls that need fresh data, such as a rank check, run through your DataForSEO or SerpApi account; SerpApi covers Google rank checks only. Reading rank history makes no provider call.
The REST API, CLI and SDKs come with the app, on Cloud or self-hosted, with no separate API plan. Paid calls cost what your provider charges, about $0.0006 for a Top 10 rank check in DataForSEO's Standard queue, plus 30% with Cloud credits.
TypeScript, Python and Go. They share one retry policy: a 30-second timeout per attempt and two retries on 429, 503 and network errors for idempotent requests. The CLI covers the terminal.
A project API key gives one service access to one project. A personal access token acts as you across your projects, and the CLI creates one when you sign in. Both carry a scope and an expiry; a token never exceeds your project role.
Sign up, create an API key and make your first call from curl, the CLI or an SDK.