# POST /v1/backlinks/changes

Links gained and lost for a target over a date window, with anchor, dofollow and source authority on each change.

**Credits:** 50 credits per call.

**Timeout:** 60s

## Parameters

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `target` | string | yes | — | Domain or URL to report link changes for. Required. |
| `type` | string | no | "both" | Which changes to return. One of: both, lost, new. Optional, default "both". |
| `date_from` | string | no | — | ISO YYYY-MM-DD, inclusive. Optional, default 30 days ago. |
| `date_to` | string | no | — | ISO YYYY-MM-DD, inclusive. Optional, default today. |
| `limit` | integer | no | 100 | Optional, default 100. 1-1000. |

## Request

```http
POST /v1/backlinks/changes HTTP/1.1
Authorization: Bearer sof_live_your_key_here
Content-Type: application/json

{
  "target": "example.com",
  "type": "both",
  "limit": 100
}
```

## Response

Wrapped in the standard envelope (id, object, created_at, elapsed_ms, cache, credits) -- documented once on The Contract. The body below is a real envelope with this endpoint's `data` shape; values vary per request, and a `…` marks an array cut short for display.

```json
{
  "id": "back_5e7u2weihnknvgowb74h5yqb",
  "request_id": "req_ofmvlhkleroyvhhgleotjusyta",
  "object": "backlink_changes",
  "created_at": "2026-07-29T12:00:00Z",
  "elapsed_ms": 180,
  "cache": "miss",
  "credits": {
    "charged": 50,
    "balance": 9857
  },
  "data": {
    "target": "example.com",
    "items": [
      {
        "event": "new",
        "source": "https://blog.example.org/post",
        "target": "https://example.com/pricing",
        "occurred_at": "2026-08-19",
        "anchor": "pricing page",
        "dofollow": true,
        "source_authority": 54,
        "source_spam_score": 2
      },
      {
        "event": "lost",
        "source": "https://news.example.net/2025/roundup",
        "target": "https://example.com/",
        "occurred_at": "2026-08-11",
        "anchor": "example",
        "dofollow": true,
        "source_authority": 61,
        "source_spam_score": 0
      },
      "…"
    ],
    "new_count": 34,
    "lost_count": 9,
    "coverage": {
      "from": "2026-07-27",
      "observations": 43
    }
  }
}
```

## Response fields

What each field in `data` (above) means.

| Field | Description |
| --- | --- |
| `data.target` | The domain or URL you requested. |
| `data.items` | Links gained and lost in the window, newest first. NOTE: when `type` is "new" or "lost", this list can come back shorter than the full window holds -- the filter is applied after the upstream has truncated the interleaved new+lost list to `limit`. `new_count`/`lost_count` are unaffected and always describe the whole window. |
| `data.items[].event` | "new" if the link was gained, "lost" if it was lost. |
| `data.items[].source` | URL the link comes from. |
| `data.items[].target` | URL the link points to. |
| `data.items[].occurred_at` | Date the change was observed. |
| `data.items[].anchor` | Anchor text, or null if unknown. |
| `data.items[].dofollow` | True when the link passes authority. |
| `data.items[].source_authority` | Authority of the linking page, 0-100, or null. |
| `data.items[].source_spam_score` | Spam score of the linking page, or null. |
| `data.new_count` | Links gained across the whole window, before any `type` filter. |
| `data.lost_count` | Links lost across the whole window, before any `type` filter. |
| `data.coverage` | What the window covers. |
| `data.coverage.from` | First date included. |
| `data.coverage.observations` | Total changes observed in the window. |
