---
title: "Read async job result"
method: POST
path: "/wrapped/credits/calls/{callId}/result"
tags: ["Burn"]
---

# Read async job result

`POST /wrapped/credits/calls/{callId}/result`

## Request

- Base URL: `https://api.paywithlocus.com/api`
- URL: `https://api.paywithlocus.com/api/wrapped/credits/calls/{callId}/result`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer
  - HTTP bearer

Read the provider result of an async job, such as clado/bulk-contacts. Pass the apiCallId returned by the submit call. Locus reads the job id from that call's receipt. Reads are free and never create a new charge, so polling the same call again is safe. Access follows the submit endpoint's scope. Set waitSeconds to wait on the server for up to 45 seconds. When state is pending, call again after pollAfterMs. When nextPage is present, call again with its skip and limit to read the next page. A call that started no provider job, such as a call sent with Prefer: respond-async, returns its own stored outcome instead: state, the httpStatus and body the call would have returned, and billing for the read.

## Path parameters

- `callId` string, uuid, required

## Headers

- `X-Locus-Session-Id` string
- `X-Locus-End-User` string: Case-sensitive immutable ID in the tenant namespace. Prefer an identity-provider subject, not an email address.

## Request body

- object
  - `waitSeconds` integer: Seconds to wait on the server for the job to finish. 0 reads the current state once.
  - `skip` integer: Result offset for paged results. Copy it from nextPage.
  - `limit` integer: Results per page for paged results. Copy it from nextPage.

## Response `200`

Job state and provider result. No credits charged.

- union
  - object: A call that started a provider job.
    - `apiCallId` string, uuid, required
    - `provider` string, required
    - `endpoint` string, required: The submit endpoint.
    - `statusEndpoint` string, required: The provider status endpoint Locus read.
    - `jobId` string, required
    - `state` 'pending' | 'completed' | 'failed', required
    - `pollAfterMs` integer: Present when state is pending.
    - `nextPage` object: Present when more result pages remain. Pass these values as skip and limit.
      - `skip` integer, required
      - `limit` integer
    - `result` unknown, required
    - `billing` object, required
      - `chargedCredits` string, required
  - object: A call that started no provider job: its stored outcome.
    - `apiCallId` string, uuid, required
    - `state` 'pending' | 'completed' | 'failed', required
    - `pollAfterMs` integer: Present when state is pending: the call is still running.
    - `httpStatus` integer: The HTTP status the call returned. Present unless state is pending.
    - `result` unknown
    - `billing` object, required
      - `chargedCredits` string, required: Charge for this read (always 0). The call's own charge is on GET /wrapped/credits/calls/{callId}.

## Other responses

- `400`: Invalid waitSeconds, skip, or limit (invalid_request), or skip or limit sent for a result that is not paged (pagination_unsupported)
- `403`: Credential cannot call the submit endpoint (credential_endpoint_denied)
- `404`: No call or job for this call id is visible to this credential, or the provider no longer has the job (job_not_found)
- `424`: The provider status read failed. Retry; reads are free (upstream_error)
- `429`: Tenant rate limit exceeded

---

[API](https://skmtc.dev/paywithlocus/apis/locus-pro-api.md) - [All operations](https://skmtc.dev/paywithlocus/apis/locus-pro-api/llms.txt) - [OpenAPI document](https://skmtc.dev/paywithlocus/apis/locus-pro-api/revisions/aab8fa5d6cef?raw)
