> ## 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.

# Schemas

> Discover the schemas provisioned for your account and the input keys each one requires.

A [**schema**](/guides/concepts#schema) defines the structured output fields a request returns and which inputs are required to submit one. Pass its `schemaId` on `POST /v1/requests` to invoke it.

Two endpoints make request creation self-service: discover the schemas your account is provisioned for, and look up the input keys each one needs.

| Endpoint                                                                                                                             | Purpose                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| [`GET /v1/schemas`](/api-reference/schemas/list-schemas)                                                                             | List the schemas owned by the account associated with your API key.                                                                         |
| [`GET /v1/schemas/{schemaId}/required-inputs`](/api-reference/schemas/required-inputs-for-a-schema)                                  | Return the input keys required to submit a request against a given schema.                                                                  |
| [`POST /v1/schemas/{schemaId}/required-payer-inputs`](/api-reference/schemas/resolve-payer-names-against-a-schema-s-required-inputs) | Resolve a batch of payer names to their per-payer required inputs (opt-in: see [Per-Payer Required Inputs](/guides/payer-required-inputs)). |

Both endpoints use the same bearer-token authentication as the rest of the API. All non-2xx responses use the uniform `{error, message, [details]}` envelope (see [Errors](#errors)).

## List your schemas

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

### Response

```json theme={null}
{
  "schemas": [
    {
      "schemaId": "fWxzG4nqtpHsJxS5Lm3q",
      "name": "Claim Status (Commercial)",
      "requestType": "claim-status"
    },
    {
      "schemaId": "qP2bN8rT6mK1xC3vW9aL",
      "name": "Verification of Benefits",
      "requestType": "vob"
    }
  ]
}
```

| Field         | Type   | Notes                                                                                                                                                                                                                                       |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `schemaId`    | string | Pass to [`POST /v1/requests`](/guides/creating-a-request) as `schemaId`.                                                                                                                                                                    |
| `name`        | string | Human-readable label. Falls back to the `schemaId` when no name is set.                                                                                                                                                                     |
| `requestType` | string | The kind of extraction this schema produces (e.g. `claim-status`, `vob`). Server-derived. Useful for filtering the list, but you don't pass it on `POST /v1/requests`. It surfaces on `RequestResponse.requestType` after the request runs. |

Schemas that are no longer accessible for your account are filtered out of this list.

## Look up required and optional inputs

Once you have a `schemaId`, fetch the input keys it accepts. The response carries two sorted, disjoint lists: `requiredInputs.fields` (must be supplied or you get `INVALID_INPUTS`) and `optionalInputs.fields` (accepted but not required, useful for "build a request" forms that want to surface every accepted key).

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

### Response

```json theme={null}
{
  "schemaId": "fWxzG4nqtpHsJxS5Lm3q",
  "requiredInputs": {
    "fields": [
      "beginningDateOfService",
      "billingProviderName",
      "billingProviderTaxId",
      "claimChargeAmount",
      "memberId",
      "patientDateOfBirth",
      "patientFirstName",
      "patientLastName",
      "payerName",
      "phoneNumber",
      "renderingProviderName",
      "renderingProviderNpi"
    ]
  },
  "optionalInputs": {
    "fields": [
      "memberId2"
    ]
  }
}
```

Field-name keys are returned verbatim: the same names the `POST /v1/requests` validator expects in `inputs`. If SuperDial updates the schema, call this endpoint again (or refresh your cache) before relying on a fixed list in code.

<Note>
  If your account is enabled for [payer phone number lookup](/guides/payer-resolution), `phoneNumber` moves out of `requiredInputs.fields` and into `optionalInputs.fields` for this endpoint, because you can omit it and let SuperDial fill it in from `payerName`. With lookup off (the default), `phoneNumber` stays required.
</Note>

<Note>
  If your account is enabled for [per-payer required inputs](/guides/payer-required-inputs), some payers require additional inputs that aren't listed here. Treat this list as the baseline; a request for one of those payers may need more.
</Note>

## End-to-end discovery flow

```python theme={null}
import requests

BASE = "https://robodialer-service-api-9nc4t1p9.uc.gateway.dev"

def list_schemas(token):
    r = requests.get(f"{BASE}/v1/schemas", headers={"Authorization": f"Bearer {token}"})
    r.raise_for_status()
    return r.json()["schemas"]

def schema_inputs(token, schema_id):
    r = requests.get(
        f"{BASE}/v1/schemas/{schema_id}/required-inputs",
        headers={"Authorization": f"Bearer {token}"},
    )
    r.raise_for_status()
    body = r.json()
    return body["requiredInputs"]["fields"], body["optionalInputs"]["fields"]

# Use it
schemas = list_schemas(token)
schema = next(s for s in schemas if s["requestType"] == "claim-status")
required, optional = schema_inputs(token, schema["schemaId"])
print("required:", required)
# ['beginningDateOfService', 'billingProviderName', ..., 'phoneNumber']
print("optional:", optional)
# ['memberId2']
```

After this you have everything you need to call [`POST /v1/requests`](/guides/creating-a-request): pass the `schemaId` and populate every key in `required` inside the `inputs` object. The `requestType` is server-derived; you'll see it on the response.

## Errors

Every non-2xx response uses the uniform envelope:

```json theme={null}
{
  "error": "MACHINE_CODE",
  "message": "Human-readable description.",
  "details": { /* optional, only on INVALID_INPUTS */ }
}
```

| HTTP code | `error` code        | When                                                                                                                                                        |
| --------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`     | `INVALID_REQUEST`   | The `schemaId` path parameter was empty, contained `/`, started with `_` or `.`, or exceeded 1500 characters. Only applies to the required-inputs endpoint. |
| `401`     | (gateway envelope)  | Bearer token missing, malformed, or expired. The gateway uses `{code, message}`, not the envelope above.                                                    |
| `404`     | `SCHEMA_NOT_FOUND`  | No schema with that ID exists for your account, or it has been retired and is no longer accessible.                                                         |
| `404`     | `ACCOUNT_NOT_FOUND` | The API key resolves to an account that no longer exists. Contact support.                                                                                  |
| `500`     | `INTERNAL_ERROR`    | Unexpected server failure. Retry once; escalate if persistent.                                                                                              |

### Example error responses

```json theme={null}
// 400: invalid schemaId path parameter
{
  "error": "INVALID_REQUEST",
  "message": "The provided schemaId is invalid."
}
```

```json theme={null}
// 404: schema not found, or has been retired
{
  "error": "SCHEMA_NOT_FOUND",
  "message": "No schema with that ID exists for your account."
}
```

```json theme={null}
// 404: API key doesn't resolve to a provisioned account
{
  "error": "ACCOUNT_NOT_FOUND",
  "message": "No account is associated with this API key. Contact support if you believe this is an error."
}
```

```json theme={null}
// 500: unexpected server failure
{
  "error": "INTERNAL_ERROR",
  "message": "An internal error occurred. Please try again or contact support if the problem persists."
}
```

For the full response and parameter schemas, see the [API Reference → Schemas](/api-reference/schemas/list-schemas).
