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

# Reading Requests

> Fetch a single request by ID, or list requests filtered by date or batch.

Once you've [created a request](/guides/creating-a-request), there are two ways to read it back:

* `GET /v1/requests/{requestId}`: fetch one request
* `GET /v1/requests`: list requests, filtered by date range or batch

Both return the same per-request [`RequestResponse`](/api-reference/requests/retrieve-a-request) shape, except the list endpoint omits several enrichment fields that can be large. See [Concepts → Single-request vs list response shapes](/guides/concepts#single-request-vs-list-response-shapes).

## Single request

Fetch a specific request by its `requestId`:

```bash theme={null}
curl -H "Authorization: Bearer <token>" \
  https://robodialer-service-api-9nc4t1p9.uc.gateway.dev/v1/requests/8bF7xK2mP9qR4sT6uV0w
```

<Note>
  **Read-after-write lag:** for a few seconds after a successful `POST /v1/requests`, a `GET /v1/requests/{requestId}` for the just-created ID can return `404 REQUEST_NOT_FOUND` even though the POST succeeded. If you poll, tolerate 404s for the first few seconds after create. The [webhook flow](/guides/webhooks) sidesteps this entirely: by the time the webhook fires, the request is readable.
</Note>

### Response

```json theme={null}
{
  "requestId": "8bF7xK2mP9qR4sT6uV0w",
  "requestBatchId": "pH9kJ2lM4nB6vC8xZ7Qr",
  "schemaId": "fWxzG4nqtpHsJxS5Lm3q",
  "requestType": "claim-status",
  "state": "SUCCESS",
  "inputs": {
    "payerName": "Sample Insurance Co",
    "memberId": "TEST123456789",
    "phoneNumber": "2125551234",
    "providerNpi": "1234567890",
    "dateOfService": "2026-03-15"
  },
  "results": {
    "claimStatus": "PAID",
    "paidAmount": "150.00",
    "checkNumber": "CHK998877",
    "paidDate": "2026-04-10"
  },
  "missingFields": [],
  "dateCreated": "2026-04-24T15:30:00.123456+00:00",
  "completedAt": "2026-04-24T15:32:18.987654+00:00",
  "dueDate": "2026-04-25T23:00:00+00:00",
  "internalId": "claim_internal_456",
  "internalTag": "march-batch",
  "modality": "phone_only",
  "data_completeness": null,
  "error": null,
  "payerLookup": {
    "inputPayerName": "Sample Insurance Co",
    "inputPhoneNumber": "2125551234",
    "matchedPayerName": null,
    "matchedPayerPhone": null,
    "phoneNumberToUse": "2125551234",
    "phoneNumberSource": "input"
  },
  "to": "+12125551234",
  "callDuration": "00:08:42",
  "callSummary": "Verified claim status as PAID. Check #CHK998877 issued on 2026-04-10 for $150.00."
}
```

The shape of `results` is schema-specific: keys correspond to the fields defined by the request's [schema](/guides/concepts#schema). Phone-call enrichment fields (`transcript`, `recordingDownloadUrl`, `callDuration`, `callSummary`, etc.) appear only when the request was fulfilled by a phone call, and always describe the request's first call (its last attempt, if that call itself needed more than one try). If a later, separate call also contributed to the request (see below), these top-level fields don't reflect it. `to` echoes the number that was actually dialed once a phone call has completed, whether you supplied it or SuperDial resolved it. The `payerLookup` block mirrors the [create response](/guides/creating-a-request): a six-field object (`inputPayerName`, `inputPhoneNumber`, `matchedPayerName`, `matchedPayerPhone`, `phoneNumberToUse`, `phoneNumberSource`) returned whenever [payer phone number lookup](/guides/payer-resolution) is enabled for your account. `phoneNumberToUse` / `phoneNumberSource` report the number dialed and its origin; the `matched*` fields are populated only when SuperDial dialed its own matched number (otherwise `null`, with `phoneNumberSource: "input"`). Requests fulfilled by a phone call also carry a `callSteps` summary on the single-request read (`GET /v1/requests/{requestId}`), and a successful or partial one adds a `contributingCalls` breakdown and a `resultSources` map. See [Calls behind a request](#calls-behind-a-request) below for the full, per-call view. See the [API Reference](/api-reference/requests/retrieve-a-request) for the complete field list.

### Calls behind a request

A request usually completes in a single phone call, but it can take more than one. Every call rolls up into the one request: the merged answers land in the top-level `results`, and `state` reflects the request as a whole. When more than one call is involved, the single top-level `transcript` / `callDuration` / `callSummary` / `recordingDownloadUrl` fields still only describe the first call (see above). The three fields below are how you see every call that contributed:

* **`callSteps`: the steps, one entry per step.** A step is a distinct calling effort, usually one schema (for example, verifying benefits, then checking prior authorization). Each step names the schema it ran via `schemaId` (plus a human-readable `name`) and reports its own `state` and how many required fields it captured (`fieldsCaptured` of `fieldsRequired`, with any `missingFields`). A simple request has one step; the same schema can appear in more than one step; they'll share `schemaId` but each still gets its own unique `key`. A single step can involve more than one call (a redial). `numContributingCalls` says how many. A step opened off an earlier one carries `triggeredBy` (the earlier step's `key`); the request's first step has `triggeredBy: null`. This is the *summary*: **what** was gathered, and **which schema** gathered it.
* **`contributingCalls`: the individual phone calls behind those steps, one entry per call.** Each has an opaque `id` uniquely identifying that call, handy for your own logging, or for referencing a specific call in a support request, but not something you can parse or decode. Alongside it, each entry carries that call's own transcript, recording, duration, summary, and captured fields, a `call` sequence number (`1`, `2`, …, in the order calls were placed), and a `callStep` linking it to its step in `callSteps`. Because a step can involve more than one call, there can be more entries here than in `callSteps`. A call also carries `to` when it dialed a *different* number than the request's original call. This is the *detail*: **how** it was gathered, call by call.
* **`resultSources`: the map between them.** For each field in `results` that came from a phone call, it gives the `call` number that produced it, so you can trace any answer all the way back: the `call` number identifies the exact `contributingCalls` entry, its `callStep` names the exact step in `callSteps`, and that step's `schemaId` tells you the exact schema the answer came from. Not every field in `results` is guaranteed an entry here.

In short: `callSteps` outlines the steps (and the schema behind each), `contributingCalls` lists the calls inside them, and `resultSources` ties each answer to a call. `callSteps` is present on any completed request that involved a phone call, including `PARTIAL` and `FAILURE`. `contributingCalls` and `resultSources` are added on a `SUCCESS` or `PARTIAL` request, alongside `callSteps` (a single-call request included, which simply shows one step and one call). All are omitted for digital-only results and aren't returned by the list endpoint.

There are two ways a request grows past a single call, and they show up differently across these fields:

* **Re-dials of the same effort**: one step, more than one call.
* **Follow-up steps**: more than one step, each with its own call(s), linked by `triggeredBy`.

#### One step, more than one call (re-dials)

When SuperDial has to call the same line more than once to finish a single effort (a disconnect mid-call, or a callback to pick up where it left off), all of those calls belong to **one** step. `callSteps` still has a single entry, with `numContributingCalls` reflecting the count; the calls each get their own `contributingCalls` entry sharing that step's `callStep` key; and `resultSources` points each field at whichever call actually produced it.

```json theme={null}
{
  "requestId": "8bF7xK2mP9qR4sT6uV0w",
  "state": "SUCCESS",
  "results": { "planActive": "YES", "copay": "30.00" },
  "callSteps": [
    {
      "key": "verification-of-benefits",
      "schemaId": "fWxzG4nqtpHsJxS5Lm3q",
      "name": "Verification of Benefits",
      "state": "SUCCESS",
      "fieldsRequired": 2,
      "fieldsCaptured": 2,
      "missingFields": [],
      "numContributingCalls": 2,
      "triggeredBy": null
    }
  ],
  "contributingCalls": [
    {
      "id": "9nQ4vT7xB2mK5pR8sL0w",
      "call": 1,
      "callStep": "verification-of-benefits",
      "callDuration": "00:03:41",
      "callSummary": "Reached a rep and confirmed the plan is active; call dropped before copay.",
      "fieldsCaptured": ["planActive"]
    },
    {
      "id": "3kW8yH2nR5tL9pM4vB0x",
      "call": 2,
      "callStep": "verification-of-benefits",
      "callDuration": "00:04:05",
      "callSummary": "Called the line back and obtained the $30 copay.",
      "fieldsCaptured": ["copay"]
    }
  ],
  "resultSources": { "planActive": 1, "copay": 2 }
}
```

One step, two calls. `numContributingCalls` is `2`, both `contributingCalls` share `callStep: "verification-of-benefits"`, and `resultSources` shows the split: `planActive` came from call 1, `copay` from the redial (call 2). To trace `copay` back to its source: `resultSources.copay` is `2` → `contributingCalls[1]` (the entry with `call: 2`, `id: "3kW8yH2nR5tL9pM4vB0x"`) → its `callStep` is `"verification-of-benefits"` → that `callSteps` entry's `schemaId` (`fWxzG4nqtpHsJxS5Lm3q`) is the schema that defined and captured it.

#### More than one step (follow-up)

When completing a request requires a distinct second effort (most commonly verifying benefits and then checking prior authorization on a separate call, often to a different line), that second effort is a **new step**. `callSteps` gains a second entry whose `triggeredBy` names the step it was opened off; the calls behind each step are tagged with the matching `callStep`; and `resultSources` maps each field across both steps.

```json theme={null}
{
  "requestId": "8bF7xK2mP9qR4sT6uV0w",
  "state": "SUCCESS",
  "results": {
    "planActive": "YES",
    "copay": "30.00",
    "priorAuthRequired": "YES",
    "priorAuthNumber": "PA556677"
  },
  "callSteps": [
    {
      "key": "verification-of-benefits",
      "schemaId": "fWxzG4nqtpHsJxS5Lm3q",
      "name": "Verification of Benefits",
      "state": "SUCCESS",
      "fieldsRequired": 2,
      "fieldsCaptured": 2,
      "missingFields": [],
      "numContributingCalls": 1,
      "triggeredBy": null
    },
    {
      "key": "prior-authorization",
      "schemaId": "qP2bN8rT6mK1xC3vW9aL",
      "name": "Prior Authorization",
      "state": "SUCCESS",
      "fieldsRequired": 2,
      "fieldsCaptured": 2,
      "missingFields": [],
      "numContributingCalls": 1,
      "triggeredBy": "verification-of-benefits"
    }
  ],
  "contributingCalls": [
    {
      "id": "9nQ4vT7xB2mK5pR8sL0w",
      "call": 1,
      "callStep": "verification-of-benefits",
      "callDuration": "00:06:12",
      "callSummary": "Confirmed plan active; copay $30.",
      "fieldsCaptured": ["planActive", "copay"]
    },
    {
      "id": "3kW8yH2nR5tL9pM4vB0x",
      "call": 2,
      "callStep": "prior-authorization",
      "to": "+18005559090",
      "callDuration": "00:04:48",
      "callSummary": "Prior authorization required; auth #PA556677 on file.",
      "fieldsCaptured": ["priorAuthRequired", "priorAuthNumber"]
    }
  ],
  "resultSources": {
    "planActive": 1,
    "copay": 1,
    "priorAuthRequired": 2,
    "priorAuthNumber": 2
  }
}
```

Two steps, one call each. `callSteps` shows *what* each step gathered, *which schema* gathered it (`schemaId`), and how it fared. The prior-authorization step's `triggeredBy` points back at the benefits step that opened it. `contributingCalls` shows the actual calls, call 1 for benefits, call 2 for prior authorization (which dialed a different line, so it carries `to`), each identified by its own opaque `id` and also carrying that call's full `transcript`, `recordingDownloadUrl`, and its own `results` (trimmed here for brevity). `resultSources` maps every answer to the call that produced it: `planActive` and `copay` came from call 1, `priorAuthRequired` and `priorAuthNumber` from call 2. Tracing `priorAuthNumber`: `resultSources.priorAuthNumber` is `2` → `contributingCalls[1]` (`id: "3kW8yH2nR5tL9pM4vB0x"`, `callStep: "prior-authorization"`) → the `prior-authorization` `callSteps` entry → its `schemaId` (`qP2bN8rT6mK1xC3vW9aL`), a different schema than the one that produced `planActive`.

### Errors

All non-2xx responses use the uniform `{error, message, [details]}` envelope.

| HTTP code | `error` code        | Meaning                                                                    |
| --------- | ------------------- | -------------------------------------------------------------------------- |
| `200`     | None                | Request found                                                              |
| `401`     | (gateway envelope)  | Missing or invalid bearer token                                            |
| `404`     | `REQUEST_NOT_FOUND` | The request ID doesn't exist for your account                              |
| `404`     | `ACCOUNT_NOT_FOUND` | The API key resolves to an account that no longer exists. Contact support. |
| `500`     | `INTERNAL_ERROR`    | Unexpected server failure                                                  |

## Listing requests

`GET /v1/requests` returns multiple requests, filtered by query parameters:

```bash theme={null}
curl -H "Authorization: Bearer <token>" \
  "https://robodialer-service-api-9nc4t1p9.uc.gateway.dev/v1/requests?dateFrom=2026-04-20&dateTo=2026-04-25"
```

The parameters and their defaults are described in the table below; see the [API Reference for `GET /v1/requests`](/api-reference/requests/list-requests) for the full request schema and per-language code samples.

### Response

```json theme={null}
{
  "requests": [
    {
      "requestId": "8bF7xK2mP9qR4sT6uV0w",
      "requestBatchId": "pH9kJ2lM4nB6vC8xZ7Qr",
      "state": "SUCCESS",
      "results": { "claimStatus": "PAID", "paidAmount": "150.00" },
      "modality": "phone_only",
      "error": null,
      ...
    },
    {
      "requestId": "aC3hN5jD8eL1fM2gK6Yo",
      "requestBatchId": "pH9kJ2lM4nB6vC8xZ7Qr",
      "state": "PROCESSING",
      "results": {},
      "modality": null,
      "error": null,
      ...
    }
  ]
}
```

Each entry follows the [`RequestResponse`](/api-reference/requests/retrieve-a-request) schema. Sorted by `dateCreated` descending (most recent first).

<Note>
  The list endpoint **omits `transcript`, `transcriptPostCall`, and `recordingDownloadUrl`, along with the per-call `callSteps`, `contributingCalls`, and `resultSources`**. When you need any of these, fetch the single-request endpoint with the `requestId` from the list. See [Concepts → Single-request vs list response shapes](/guides/concepts#single-request-vs-list-response-shapes) for the full breakdown.
</Note>

### Query parameters

| Parameter        | Format       | Default            | Notes                                                                                             |
| ---------------- | ------------ | ------------------ | ------------------------------------------------------------------------------------------------- |
| `dateFrom`       | `YYYY-MM-DD` | Today, midnight    | Inclusive                                                                                         |
| `dateTo`         | `YYYY-MM-DD` | Tomorrow, midnight | **Exclusive**                                                                                     |
| `requestBatchId` | string       | None               | Bypasses the date defaults: return all requests in the batch regardless of when they were created |

When `requestBatchId` is provided, `dateFrom` and `dateTo` are ignored. When `requestBatchId` is not provided, `dateFrom` and `dateTo` default to today's window.

### By batch

Pass `requestBatchId` as a query parameter to fetch every request under a given batch, regardless of their individual `state`, useful for tracking progress.

```python theme={null}
def batch_progress(token, batch_id):
    r = requests.get(
        f"https://robodialer-service-api-9nc4t1p9.uc.gateway.dev/v1/requests",
        params={"requestBatchId": batch_id},
        headers={"Authorization": f"Bearer {token}"},
    )
    items = r.json()["requests"]
    by_state = {}
    for item in items:
        by_state.setdefault(item["state"], 0)
        by_state[item["state"]] += 1
    return by_state
# {"SUCCESS": 4, "PARTIAL": 1, "FAILURE": 1, "PROCESSING": 2}
```

<Note>
  If your original `POST /v1/requests` batch was split across multiple `requestBatchId` values (see [Creating a Request → Batch](/guides/creating-a-request#batch)), iterate the unique `requestBatchId`s found in the create response and call this once per ID.
</Note>

### Errors

All non-2xx responses use the uniform `{error, message, [details]}` envelope.

| HTTP code | `error` code        | Meaning                                                                    |
| --------- | ------------------- | -------------------------------------------------------------------------- |
| `200`     | None                | List returned (may be empty)                                               |
| `400`     | `INVALID_REQUEST`   | `dateFrom` or `dateTo` wasn't a valid `YYYY-MM-DD` date                    |
| `401`     | (gateway envelope)  | Missing or invalid bearer token                                            |
| `404`     | `ACCOUNT_NOT_FOUND` | The API key resolves to an account that no longer exists. Contact support. |
| `500`     | `INTERNAL_ERROR`    | Unexpected server failure                                                  |

## Reading after a webhook

The recommended end-to-end pattern is:

1. [Create a request](/guides/creating-a-request) with `internalId` so you can correlate.
2. Receive the [webhook](/guides/webhooks) when the request reaches a terminal state.
3. Call `GET /v1/requests/{requestId}` to fetch the full result.

The webhook payload is intentionally compact (`requestId`, `requestBatchId`, `state`, optional `internalId`/`internalTag`). It tells you *that* the request is done; the GET fetches the actual `results`, `missingFields`, `modality`, and the [`error`](/guides/concepts#error-object) object on `FAILURE`.
