# Get incremental batch result entries

Read a batch job's result entries as an incremental, cursor-paged feed.

**GET** `https://api.up2data.ai/v1/batch/{job_id}/results`

**Credits:** Free - **Mode:** synchronous

A cursor page of immutable, first-seen result entries; free, and safe to poll while the job is still processing. Pass the previous response's `next_cursor` back as `cursor` until `has_more` is false. `job_id` is a path parameter; `cursor` and `limit` are query parameters on the same request. Every entry carries the `operation` that produced it (e.g. `enrich.profile`, `profiles.activity`, `search.jobs`) and `input`, echoing what you submitted for it - the url string when the item was identified by url, or its request body otherwise.

## Request

| Field | Type | Notes |
|---|---|---|
| `job_id` **required** | `string` | Path parameter. The job_id returned by POST /batch. |
| `cursor` | `string` | Query parameter. Opaque delivery_seq cursor from a prior response. Omit for the first page. |
| `limit` | `integer` | Query parameter. 1 to 1,000, default 100. |

## Call it

**cURL**

```bash
curl -X GET "https://api.up2data.ai/v1/batch/job_7hd92kfa/results?cursor=eyJkZWxpdmVyeV9zZXEiOjJ9&limit=100" \
  -H "X-API-Key: YOUR_API_KEY"
```

**Python**

```python
import requests

url = "https://api.up2data.ai/v1/batch/job_7hd92kfa/results?cursor=eyJkZWxpdmVyeV9zZXEiOjJ9&limit=100"
headers = {
    "X-API-Key": "YOUR_API_KEY",
}

response = requests.get(url, headers=headers)
print(response.json())
```

**Node**

```javascript
const url = "https://api.up2data.ai/v1/batch/job_7hd92kfa/results?cursor=eyJkZWxpdmVyeV9zZXEiOjJ9&limit=100";
const headers = {
  "X-API-Key": "YOUR_API_KEY",
};

const response = await fetch(url, {
  method: "GET",
  headers,
});
const data = await response.json();
console.log(data);
```

**Go**

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.up2data.ai/v1/batch/job_7hd92kfa/results?cursor=eyJkZWxpdmVyeV9zZXEiOjJ9&limit=100"
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", "YOUR_API_KEY")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	respBody, _ := io.ReadAll(resp.Body)
	fmt.Println(string(respBody))
}
```

## Response

**200**

```json
{
  "data": {
    "job_id": "job_7hd92kfa",
    "status": "processing",
    "results_available": 3,
    "entries": [
      { "delivery_seq": 3, "item_index": 2, "entry_key": "https://linkedin.com/in/c", "operation": "enrich.profile", "input": "https://linkedin.com/in/c", "data": { "full_name": "Sam Example", "headline": "VP Sales at Example Corp", "url": "https://linkedin.com/in/c" }, "final_rank": 2 }
    ],
    "next_cursor": "eyJkZWxpdmVyeV9zZXEiOjN9",
    "has_more": true,
    "recommended_poll_ms": 2000
  },
  "meta": { "creditsUsed": 0, "creditsRemaining": 421032, "billed": false, "reason": "poll", "requestId": "req_example" }
}
```

## Errors

| Status | Type | When | Billed |
|---|---|---|---|
| 400 | `invalid_request` | A malformed cursor, or limit out of the 1 to 1,000 range. | No |
| 401 | `invalid_api_key` | Missing, malformed, or revoked key. | No |
| 404 | `not_found` | No job with this job_id. | No |
| 429 | `rate_limited` | Over the 5,000 requests/min limit. Honor Retry-After. | No |
| 500 | `internal_error` | Something broke on the server side. | No |

See the [Errors guide](https://up2data.ai/docs/v1/guides/errors/) for every error type this version can return.
