> ## Documentation index
> Fetch the complete documentation index at: https://rankfield.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Scrape job results

> Read a Scrape job's items as each one finishes, with its full answer or error, and page through them with a cursor.

`GET https://rankfield.dev/v1/scrape/jobs/{id}/results`

```bash cURL
curl 'https://rankfield.dev/v1/scrape/jobs/8f14e45fceea167a5a36dedd4bea2543/results?cursor=0&limit=100' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

```python Python
import requests

response = requests.get(
    "https://rankfield.dev/v1/scrape/jobs/8f14e45fceea167a5a36dedd4bea2543/results?cursor=0&limit=100",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
print(response.json())
```

```javascript JavaScript
const response = await fetch("https://rankfield.dev/v1/scrape/jobs/8f14e45fceea167a5a36dedd4bea2543/results?cursor=0&limit=100", {
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});
console.log(await response.json());
```

```json 200
{
  "job": {
    "id": "8f14e45fceea167a5a36dedd4bea2543",
    "status": "done",
    "total": 2,
    "done": 1,
    "failed": 1,
    "createdAt": "2026-10-26T18:00:00Z",
    "finishedAt": "2026-10-26T18:00:04Z",
    "expiresAt": "2026-10-27T18:00:04Z"
  },
  "cursor": "2",
  "hasMore": false,
  "items": [
    { "index": 0, "ok": true, "result": { "…": "the same answer as a single call" } },
    { "index": 1, "ok": false, "error": { "code": "fetch_failed", "message": "…", "details": { "reason": "dns" } } }
  ]
}
```

## Parameters

### Headers

| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `Authorization` | string | Yes | – | `Bearer` followed by your API key. See [Authentication](/docs/get-started/authentication). |

### Path parameters

| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `id` | string | Yes | – | The job id from [Start a Scrape job](/docs/scrape/start-a-job). |

### Query parameters

| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| `cursor` | integer | No | `0` | Where to continue: the `cursor` of the previous answer (returned as a string; send it back as it is). |
| `limit` | integer | No | `100` | Items per answer, 1–500. |

## Read results

Start with `cursor=0`. Read `items`, then ask again with the returned `cursor` while `hasMore` is `true`. Items arrive in the order they finish; `index` is the item's position in your `items`, from 0.

| Field | Type | Description |
|---|---|---|
| `job` | object | The job, as in [Get a Scrape job](/docs/scrape/get-a-job). |
| `items[].index` | integer | Position in your `items`. |
| `items[].ok` | boolean | Whether the item succeeded. |
| `items[].result` | object | The same answer as [Scrape a page](/docs/scrape/scrape-a-page). |
| `items[].error` | object | `{code, message, details}`, as a single call's error. |
| `cursor` | string | Pass it back to continue. |
| `hasMore` | boolean | Whether more items exist now or will. |

## Errors

| Status | Code | When |
|---|---|---|
| 400 | `invalid_input` | `cursor` or `limit` is invalid. |
| 401 | `unauthorized` | No valid API key. |
| 404 |  | No job with this id for this key, or it has expired. This answer has no `code`: `{"error":{"message":"Not found"}}`. |

## MCP

On the [MCP server](/docs/agents/mcp-server), the tool for this is `get_scrape_results`.
