# Get Results for a Query Job

Gets the results for a query job. The job must have the state `JobComplete`.

:::tip
If encoding is enabled for Bulk API 2.0 Query job responses, there is a significant improvement in performance of query result downloads. This not the total query time, but a reduction in the time to download the results.
:::

## Syntax

**URI:**

`/services/data/vXX.X/jobs/query/queryJobId/results`

or

```nolang
/services/data/vXX.X/jobs/query/queryJobId/results
   ?locator=locator
   &maxRecords=maxRecords
```

:::note
Use the same API version to get query results that you used to create the query. Otherwise, the call returns a 409 error.
:::

**Available since release:**

This resource is available in API version 47.0 and later.

**Formats:** CSV

**HTTP methods:** GET

**Authentication:** Authorization: Bearer token

**Request parameters:**

<sfdocstbl><table>

<col>
</col>
<col>
</col>
<col>
</col>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    <th>
      Description
    </th>
    <th>
      Required or Optional
    </th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>
      <code>queryJobId</code>
    </td>
    <td>
      The ID of the query job.
    </td>
    <td>
      Required
    </td>
  </tr>
  <tr>
    <td>
      <code>locator</code>
    </td>
    <td>
      A string that identifies a specific set of query results. Providing a value for this parameter returns only that set of results.
      <p>
        Omitting this parameter returns the first set of results.
      </p>
      <p>
        You can find the locator string for the next set of results in the response of each request. See
        <a href="#example">Example</a>
        and
        <a href="query_get_all_jobs.md#rules-and-guidelines">Rules and Guidelines</a>
        .
      </p>
      <p>
        As long as the associated job exists, the locator string for a set of results does not change. You can use the locator to retrieve a set of results multiple times.
      </p>
    </td>
    <td>
      Optional
    </td>
  </tr>
  <tr>
    <td>
      <code>maxRecords</code>
    </td>
    <td>
      The maximum number of records to retrieve per set of results for the query. The request is still subject to the size limits.
      <p>
        If you are working with a very large number of query results, you may experience a timeout before receiving all the data from Salesforce. To prevent a timeout, specify the maximum number of records your client is expecting to receive in the
        <code>maxRecords</code>
        parameter. This splits the results into smaller sets with this value as the maximum size.
      </p>
      <p>
        If you don’t provide a value for this parameter, the server uses a default value based on the service.
      </p>
    </td>
    <td>
      Optional
    </td>
  </tr>
</tbody>
</table></sfdocstbl>

**Response Body**

If the request is successful, the status code is 200 (OK) and the request body contains the results of the job’s query. For example:

```nolang
"Id","Name"
"005R0000000UyrWIAS","Jane Dunn"
"005R0000000GiwjIAC","George Wright"
"005R0000000GiwoIAC","Pat Wilson"
...
```

:::note
In API version 50.0 and later, the order of the columns returned by the query is the same as the order you requested them. In version 49.0 and earlier, the order of the columns is returned alphabetically.
:::

**Response Headers**

<sfdocstbl><table>

<col>
</col>
<col>
</col>
<thead>
  <tr>
    <th>
      Header
    </th>
    <th>
      Description
    </th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>
      <code>Sforce-NumberOfRecords</code>
    </td>
    <td>
      The number of records in this set.
    </td>
  </tr>
  <tr>
    <td>
      <code>Sforce-Locator</code>
    </td>
    <td>
      The locator for the next set of results (if there are any). Use this value in other
      <code>GET</code>
      request to retrieve the next set of query results.
      <p>
        This value is a pseudo random string (for example,
        <code>MTAwMDA</code>
        ). The length of this string varies depending on how many sets of results there are.
      </p>
      <p>
        If there are no more sets of query results, this value is the string ‘null’.
      </p>
      <p>
        See
        <a href="#example">Example</a>
        and
        <a href="query_get_all_jobs.md#rules-and-guidelines">Rules and Guidelines</a>
        .
      </p>
    </td>
  </tr>
</tbody>
</table></sfdocstbl>

## Example

This example retrieves the results for the job with ID `750R0000000zxr8IAA`. It also shows how to use the `locator` and `maxRecords` query parameters. (In this example, we use them both, but they are independent. You don’t have to use them together.) For an example on how to download data in parallel, see [Get Parallel Results for a Query Job](/docs/platform/api-asynch/guide/query-get-parallel-job-results.md).

We start by sending an initial request to retrieve the first set of query results. We don’t use the `locator` parameter because we want to get the first set of results.

```nolang
curl --include --request GET \
--header "Authorization: Bearer TOKEN" \
--header "Accept: text/csv" \
https://INSTANCE.salesforce.com/services/data/vXX.X/jobs/query/750R0000000zxr8IAA/results
?maxRecords=50000
```

:::note
The `Accept` header must match what was specified when the job was created. Currently, only `text/csv` is supported.
:::

The response body is:

```nolang
HTTP/1.1 200 OK
...
Sforce-Locator: MTAwMDA
Sforce-NumberOfRecords: 50000
...

"Id","Name"
"005R0000000UyrWIAS","Jane Dunn"
"005R0000000GiwjIAC","George Wright"
"005R0000000GiwoIAC","Pat Wilson"
...
```

The response includes `MTAwMDA` as a value for the `Sforce-Locator` header. This value is not ‘null’, which means that there are more query results that we can retrieve.

To retrieve the next set of query results, we send another request, using the `locator` parameter and the locator string, `MTAwMDA`.

```nolang
curl --include --request GET \
--header "Accept: text/csv" \
https://INSTANCE.salesforce.com/services/data/vXX.X/jobs/query/750R0000000zxr8IAA/results
?locator=MTAwMDA&maxRecords=50000
```

The response body is:

```nolang
HTTP/1.1 200 OK
...
Sforce-Locator: MjAwMDAw
Sforce-NumberOfRecords: 50000
...

"Id","Name"
"005R0000000UyrWIAv","James Wu"
"005R0000000GiwjIxx","Samantha Jones"
"005R0000000GiwoIAB","Doug West"
...
```

Notice that the locator value has changed. This means that there is another set of query results that we can retrieve. We use the new locator string, `MjAwMDAw`, in another request.

```nolang
curl --include --request GET \
--header "Accept: text/csv" \
https://INSTANCE.salesforce.com/services/data/vXX.X/jobs/query/750R0000000zxr8IAA/results
?locator=MjAwMDAw&maxRecords=50000
```

We repeat this process until the value of the `Sforce-Locator` header is ‘null’, which indicates that there are no more results to retrieve.

```nolang
HTTP/1.1 200 OK

Sforce-Locator: null
Sforce-NumberOfRecords: 6155
...

"Id","Name"
...
```

## Rules and Guidelines

To retrieve your full set of query results, follow these rules and guidelines.

1. Use `/services/data/vXX.X/jobs/query/queryJobId/results` to get the first set of results for the job.

2. If there are no more results, the `Sforce-Locator` header’s value is the string ‘null’. Otherwise, set the `locator` query parameter to that value to get the next set of results.

   :::note
   For `locator`, use only the value from the `Sforce-Locator` header. Don’t try to guess what it is. How this parameter is evaluated is subject to change.
   :::

3. Repeat this process until the `Sforce-Locator` header’s value is the string ‘null’. That set is the last set of results.

**See Also**

- [Errors](/docs/platform/api-asynch/guide/bulk-api-2-0-errors.md)
