---
title: "Analyze backlinks"
method: GET
path: "/projects/{project_id}/backlinks"
tags: ["backlinks"]
---

# Analyze backlinks

`GET /projects/{project_id}/backlinks`

## Request

- Base URL: `https://eu.bisibility.com/api/v1`
- URL: `https://eu.bisibility.com/api/v1/projects/{project_id}/backlinks`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `/api/auth/oauth2/authorize`, token URL `/api/auth/oauth2/token`, scopes: `api:write`)

Requires write scope because cache misses spend provider budget. estimate_only=true needs only read scope and never spends provider budget. estimate_only is a free dry run, and max_cost_cents limits admitted cost estimates across summary, history, rows and retries. Confirmed provider charges can differ from estimates. Snapshots are cached for 24 hours. Aggregated referring-domain, page, and anchor views are consumer-side and must be labeled "within fetched rows".

## Path parameters

- `project_id` string, required: Public project ID; membership and token scope are enforced.

## Query parameters

- `target` string, required
- `target_scope` 'site' | 'page'
- `include_subdomains` boolean
- `result_limit` 100 | 300 | 500 | 1000
- `mode` 'as_is' | 'one_per_domain'
- `estimate_only` boolean
- `fresh` boolean
- `max_cost_cents` integer

## Headers

- `Bisibility-API-Version` 'v1'
- `X-Bisibility-Source` 'sdk' | 'cli' | 'mcp'

## Response `200`

JSON response

- BacklinksResponse
  - `data` union, required
    - object: Free dry run returned for estimate_only=true. It carries cost facts only and never report fields, so it cannot be mistaken for an empty backlink profile.
      - `cached` boolean, required: An unexpired snapshot exists, so the paid call would cost nothing.
      - `cached_until` string, date-time, nullable, required: Expiry of that snapshot; null when there is none.
      - `cost_cents` number, required: 0 when cached, otherwise equal to estimated_cost_cents.
      - `estimate` true, required
      - `estimated_cost_cents` number, required
      - `include_subdomains` boolean, required
      - `provider` string, required
      - `target` string, required
      - `target_scope` 'site' | 'page', required
    - object
      - `history` unknown
      - `history_unavailable` unknown
      - `target_scope` 'site', required
    - object
      - `history` unknown
      - `history_unavailable` unknown, required
    - object
      - `history` unknown
      - `history_unavailable` unknown
      - `target_scope` 'page', required

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `402`: Deployment credits exhausted for a paid provider request
- `403`: Forbidden, or `byok_required`: the account runs paid provider work only on its own provider keys and none serves this request
- `404`: Not found
- `409`: Unsupported API version
- `422`: unsupported_target from local validation before any paid call, needs_reauth, or cost_limit_exceeded
- `429`: budget_exhausted, in_progress, or rate_limited
- `500`: Unexpected failure, optionally carrying completed summary evidence after history failed. No rows were requested and total cost remains unknown.

---

[API](https://skmtc.dev/bisibility/apis/bisibility-public-api.md) · [All operations](https://skmtc.dev/bisibility/apis/bisibility-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/bisibility/apis/bisibility-public-api/revisions/a6e1ec0dec82?raw)
