# List bulk update jobs

List your community's bulk user update jobs, newest first, so you can find a job's ID by its `log_name`.

- Endpoint: `GET https://api.returning.ai/v1/users/bulk-update`
- Section: Users and data / Bulk operations
- Authentication: `Authorization: Bearer <API_KEY>` (Community API key)
- Permission: `getBulkUpdate` (Shown in the dashboard as "Get Bulk Update History")
- Retries: Read-only; exact retries are safe
- Guide: hand-written
- Verified: live, 2026-09-27
- Last updated: 26 Sep 2026
- Web page: https://docs.returning.ai/api-reference/bulk-operations/list-bulk-update-jobs

## When to use this

- Find the `_id` of a job you just uploaded, by matching `name` to the `log_name` you sent.
- After a timeout on an upload, check whether the job was created before you upload again.
- Show recent bulk updates and their outcomes in your own tools.

**Instead:** Use [Get bulk update job status](https://docs.returning.ai/api-reference/bulk-operations/get-bulk-update-job-status.md) instead once you have the job's `_id`.

**Lower-case states:** `status` here is `queued`, `processing`, `completed` or `failed`. Get bulk update job status shows the same states as `In Queue`, `In Progress`, `Completed` and `Failed`.

## Authentication

- Header: `Authorization: Bearer <API_KEY>`
- Permission: `getBulkUpdate`

This endpoint needs `getBulkUpdate`, shown in the dashboard as Get Bulk Update History. Use a Community API key and keep it on your server. The key decides the community, so you only see that community's jobs.

## Behaviour

[Bulk update users from CSV](https://docs.returning.ai/api-reference/bulk-operations/bulk-update-users-from-csv.md) returns no job ID, so this list is how you find one. Jobs come back newest upload first. There is no filter or search: read from page 1 and match `name` to the `log_name` you sent. Names don't have to be unique, so give every upload its own `log_name`; if two jobs share one, the first match is the newer job.

The list holds jobs from Bulk update users from CSV only, whichever key in your community uploaded them. Premium currency uploads and legacy bulk imports are not listed.

## Request

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | `integer` | No | Page number, starting at 1. (Whole number, 1 or more; default 1) |
| `limit` | `integer` | No | Jobs per page. (Default 10; max 100) |

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Authorization` | `string` | Yes | Community API key with `getBulkUpdate`. (`Bearer <API_KEY>`) |

### Example request

```bash
curl --request GET \
  --url 'https://api.returning.ai/v1/users/bulk-update?page=1&limit=20' \
  --header 'Authorization: Bearer <API_KEY>'
```

## Response

A `200` returns the jobs in `data.data` and the totals in `data.pagination`. `receivedAt` changes as the job moves on, so don't use it as the upload time. For row counts, use Get bulk update job status.

If `data.pagination` is an empty object and `data.data` is empty, the list could not be read; retry with backoff.

### Response fields

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `status` | `string` | always | Result of the request. (`success`) |
| `message` | `string` | always | Human-readable summary. Do not branch on it. |
| `data` | `object` | always | Paging totals and this page of jobs. |
| `data.pagination` | `object` | always | Paging totals for all your jobs. An empty object means the list could not be read; retry. |
| `data.pagination.total` | `integer` | - | Jobs across all pages. |
| `data.pagination.totalPages` | `integer` | - | Pages at this `limit`. `0` when there are no jobs. |
| `data.pagination.currentPage` | `integer` | - | The page you asked for. |
| `data.pagination.hasNextPage` | `boolean` | - | `true` when a later page has jobs. |
| `data.pagination.hasPrevPage` | `boolean` | - | `true` when `page` is above 1. |
| `data.data` | `object[]` | always | Jobs on this page, newest upload first. Empty past the last page. |
| `data.data._id` | `string` | - | The job ID. Send it to Get bulk update job status and details. |
| `data.data.name` | `string` | - | The `log_name` sent with the upload, or `Bulk Update Users` if none was sent. |
| `data.data.status` | `string` | - | Where the job is, in lower case. (`queued`, `processing`, `completed` or `failed`) |
| `data.data.receivedAt` | `string` | - | When the job last moved to a new stage, ISO 8601 UTC. It is the upload time only while the job is `queued`. |
| `data.data.duration` | `string` | - | Processing time in seconds, as text, such as `"4.213"`. Left out until the job finishes. |

### Example response (200)

```json
{
  "status": "success",
  "message": "All bulk updates fetched successfully",
  "data": {
    "pagination": {
      "total": 2,
      "totalPages": 1,
      "currentPage": 1,
      "hasNextPage": false,
      "hasPrevPage": false
    },
    "data": [
      {
        "_id": "66f000000000000000000701",
        "receivedAt": "2026-09-26T02:00:05.000Z",
        "duration": "4.213",
        "status": "completed",
        "name": "Coins top-up 2026-09-26"
      },
      {
        "_id": "66f000000000000000000702",
        "receivedAt": "2026-09-25T02:00:03.000Z",
        "duration": "0.512",
        "status": "failed",
        "name": "Coins top-up 2026-09-25"
      }
    ]
  }
}
```

## Errors

The 401, 403 and 404 errors, and `500 AUTHENTICATION_FAILED`, come from the API key check and carry the code in `meta.code`. A `400` has no `code`; `detail` names the query field.

### Fix the request

| Status | Code | What to do |
| --- | --- | --- |
| 400 | - | `limit` is over 100, or `page` or `limit` is not a number. There is no `code`; `detail` names the field. Send `page` of 1 or more and `limit` up to 100. |
| 401 | `AUTHENTICATION_REQUIRED` | The key is missing, invalid or expired. Send `Authorization: Bearer <API_KEY>` with a current Community API key. |
| 403 | `API_KEY_PERMISSION_DENIED` | The key lacks `getBulkUpdate`, or it is a personal key. Use a Community API key and add the permission in Settings > Integration > API Keys. |

### Fix the data

| Status | Code | What to do |
| --- | --- | --- |
| 404 | `COMMUNITY_NOT_FOUND` | The community this key belongs to no longer exists. Contact Returning.AI support. |

### Retry with backoff

| Status | Code | What to do |
| --- | --- | --- |
| 500 | `AUTHENTICATION_FAILED` | The key could not be checked. Retry with backoff; nothing was read. |

**Retries:** This endpoint is read-only, so retrying the exact same request is safe after a network error or a 5xx. Use bounded exponential backoff. Listing jobs never creates or re-runs one. Over the [rate limit](https://docs.returning.ai/how-it-works.md#rate-limits), requests return `429`; wait for the window to reset, then retry.

## Next step

- [Get bulk update job status](https://docs.returning.ai/api-reference/bulk-operations/get-bulk-update-job-status.md): `GET /v1/users/bulk-update/{id}/status`. Poll the job's `_id` until it is `Completed` or `Failed`.
- [Once it's Completed, read each row with Get bulk update job details](https://docs.returning.ai/api-reference/bulk-operations/get-bulk-update-job-details.md): `GET /v1/users/bulk-update/{id}/details`.
