# API Reference
Source: https://www.stedi.com/docs/healthcare/api-reference

***

title: API Reference
sidebarTitle: "Introduction"
----------------------------

Download our OpenAPI specs

<CardGroup cols={2}>
  <Card title="Payers, claim submission, and real-time eligibility checks" icon="hospital-line" href="https://github.com/Stedi/openApi/blob/main/healthcare.json" />

  <Card title="Claim attachments" icon="attachment-2" href="https://github.com/Stedi/openApi/blob/main/claims.json" />

  <Card title="Batch eligibility" icon="stack-line" href="https://github.com/Stedi/openApi/blob/main/manager.json" />

  <Card title="Transaction enrollment" icon="arrow-left-right-line" href="https://github.com/Stedi/openApi/blob/main/enrollment.json" />
</CardGroup>

## Clearinghouse APIs

Our APIs allow you to automate business flows like [eligibility checks](/healthcare/api-reference/post-healthcare-eligibility) and [claims processing](/healthcare/api-reference/post-healthcare-claims). We also offer APIs for retrieving [Stedi's up-to-date payer list](/healthcare/api-reference/get-payers) and [provider enrollments](/healthcare/api-reference/post-enrollment-create-provider) with payers.

## Authentication

You need an API key to use any Stedi API. You pass the API key in the `Authorization` header of every request and Stedi determines which resources you can access.

### API key types

You can create two types of Stedi API keys: Test and Production.

Test API keys allow you to send mock requests to Stedi healthcare APIs and receive realistic mock responses, so you can test your integration without sending PHI or PII.

* Test keys can only be used in test mode with approved test requests. APIs that support test keys include a list of approved test requests you can send.
* Test keys are currently supported for the [Real-Time Eligibility Check](/healthcare/api-reference/post-healthcare-eligibility) API.

Production API keys allow you to send transactions to trading partners and payers. All Stedi APIs support production API keys.

### Creating an API key

To create an API key:

1. Log into your [Stedi account](https://portal.stedi.com/app).
2. Click your account name at the top right of the screen.
3. Select **API Keys**.
4. Click **Generate new API Key**.
5. Enter a name for your API key. We recommend using a unique name and adding a `test` or `production` prefix to indicate the key type.
6. Choose whether the key is for test or production use.
7. Click **Generate**. Stedi generates an API key and allows you to copy it.

<Warning>
  Make sure you copy your API key and store it in a safe location. Once you
  close the modal, Stedi will not show the API key again.
</Warning>

### API key access

Within your Stedi account, members can be assigned to roles with different permissions. Production API keys inherit the permissions of the account member who created them and keep those permissions even if the creator's role is later updated.

### Passing the API key

Every request you send needs to include an API key. You pass the API key in the `Authorization` header. For example, if your API key is `Jclcke.ZHqS3demo4dS16XZ1KeyBY7`, you would insert it into the header according to the following example:

```bash
curl --request POST \
  --url https://core.us.stedi.com/2023-08-01/x12/partnerships/{partnershipId}/generate-edi \
  --header 'Authorization: Jclcke.ZHqS3demo4dS16XZ1KeyBY7' \
  --header 'Content-Type: application/json' \
  --data '{ ... }'
```

<Note>
  Stedi supports the previous method of prefixing the API key with `Key` (e.g.
  `Authorization: Key Jclcke.ZHqS3demo4dS16XZ1KeyBY7`) for
  backwards-compatibility.
</Note>

## Pagination

When you request a list of resources, the response may contain a subset of available responses. In that case, the response will include a key called `next_page_token`. To retrieve the next page of results, repeat the request, but add the query parameter `page_token` and give it the value you received in the response.

For example, when you call the [List Transactions API](/healthcare/api-reference/get-list-transactions), the result contains a list of every transaction within your Stedi account and a token for the next page.

```javascript
{
  "items": [ ... ],
  "next_page_token": "2t7M75ZN1w4OnYFKKT0SUkT95w_ULzPR"
}
```

You can then request the next page of results like this:

```bash
  curl --request GET \
    --url https://core.us.stedi.com/2023-08-01/transactions?page_token=2t7M75ZN1w4OnYFKKT0SUkT95w_ULzPR \
    --header "Authorization: ${STEDI_API_KEY}"
```

As long as the response contains `next_page_token`, there are more results available. If a response doesn't contain `next_page_token`, then you're on the last page.

## Error Responses

If you make a request that the API can't fulfill, the response code will be in the `4xx` range and the response body will contain the following two fields.

* `error` – A code indicating what went wrong.
* `message` – A human-readable message describing what went wrong.

You can use `error` to write code that handles the error and you can use `message` when you're debugging the problem yourself. If a response needs to report multiple errors, it will include an array called `errors`, but even in that case, the `error` and `message` fields will be available at top level.

It's possible for a response to contain both a result and an error. This happens when something went wrong, but the API is able to give a partial or best-effort result.

### `403` Unauthorized

When you receive a `403` error from Stedi, it's likely due to one of the following reasons:

* Your API key is invalid or expired.
* You accidentally sent a `GET` request to an endpoint that only accepts `POST` requests.
* Your IP address was previously flagged as malicious. Stedi uses the Amazon Web Services (AWS) Web Application Filter (WAF) as a layer of security for our APIs. Our WAF configurations include AWS-managed rules that determine whether to allow or block each request. One set of rules blocks requests when the [source IP address is determined to be malicious](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-ip-rep.html#aws-managed-rule-groups-ip-rep-amazon), based on Amazon internal threat intelligence. We've seen this happen most often with requests sent from Google Cloud Platform (GCP), but it can occasionally happen with requests sent through other platforms as well. You can fix this issue by routing your requests through a dedicated virtual private cloud (VPC) with a static IP address.

## Concurrency limits

Stedi's clearinghouse endpoints are subject to the following concurrency limits per customer account. These limits are based on *concurrent* requests, not requests per second. To request an increase to your default account concurrency limits, contact Stedi support in Slack or Teams.

When endpoints share a concurrency pool, it means the total number of in-flight requests across all endpoints in the pool cannot exceed the shared limit.

{/* prettier-ignore-start */}

| Endpoints                                                                                                                                                                                                                                                                                   | Shared pool | Default concurrency limit |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------- |
| <ul><li>Real-time eligibility check JSON</li><li>Real-time eligibility check Raw X12</li><li>Real-time claim status JSON</li><li>Real-time claim status Raw X12</li></ul>                                                                                                                   | Yes         | 50                        |
| <ul><li>Professional claims JSON</li><li>Professional claims Raw X12</li><li>Institutional claims JSON</li><li>Dental claims JSON</li><li>Dental claims Raw X12</li><li>Create claim attachment JSON</li><li>Submit claim attachment JSON</li><li>Submit claim attachment Raw X12</li></ul> | Yes         | 100                       |
| <ul><li>CMS-1500 PDF: Business Identifier</li><li>CMS-1500 PDF: Transaction ID</li><li>277CA Report</li><li>835 ERA Report</li></ul>                                                                                                                                                        | Yes         | 100                       |
| Coordination of Benefits Check                                                                                                                                                                                                                                                              | No          | 50                        |
| Insurance Discovery Check                                                                                                                                                                                                                                                                   | No          | 5                         |
| Insurance Discovery Check Results                                                                                                                                                                                                                                                           | No          | 5                         |

{/* prettier-ignore-end */}

When you reach the maximum concurrency limit for an endpoint, Stedi rejects additional requests with a `429` HTTP status code until one of your previous requests is completed. Rejected requests have the following error message:

```json
{
  "message": "The request can't be submitted because the sender's submission has been throttled: CUSTOMER_LIMIT",
  "code": "TOO_MANY_REQUESTS"
}
```

## API clients

We strongly recommend determining the HIPAA and/or other security requirements for your organization before you begin testing with an API client. At a minimum, if you're testing APIs that handle PHI (Protected Health Information) from your local machine, we recommend using a client that defaults to local-only storage.

### Not recommended

We **don't recommend** using Postman for requests containing Protected Health Information (PHI) because Postman defaults to storing request history - including full request payloads - on its cloud servers. You can’t turn this feature off without impractical workarounds. So if your company doesn't have a BAA in place with Postman, you could unintentionally fall short of HIPAA requirements when testing.

You can learn more about why Postman isn't safe for requests containing PHI in our blog: [Postman is probably not HIPAA compliant](https://www.stedi.com/blog/postman-is-probably-not-hipaa-compliant).

### Recommended

The following open-source API clients have an offline-first approach. Each client also supports OpenAPI imports, which you can use to import the Stedi OpenAPI specs.

* [Bruno](https://www.usebruno.com/): A local-only API client built to avoid cloud syncing. Bruno has several interfaces, including a desktop app, CLI, and VS Code extension. [GitHub repository](https://github.com/usebruno/bruno)
* [Pororoca](https://pororoca.io/): A desktop-only API client with no cloud sync, built for secure local testing. Poroca’s data policy states that no data is synced to remote servers. [GitHub repository](https://github.com/alexandrehtrb/Pororoca)
* [Yaak](https://yaak.app/): A simple, fast desktop API client. Yaak supports several import formats, including Postman collections, OpenAPI, and Insomnia. [GitHub repository](https://github.com/mountain-loop/yaak)

Ensure your security and compliance teams review the tool you choose carefully, especially because applications evolve over time.

## Idempotency keys

Idempotency allows you to make an API request multiple times without causing different outcomes. Adding idempotency keys to requests can prevent sending duplicate data to your trading partners in the case of network errors or other intermittent failures.

You can safely retry requests with the same idempotency key as many times as necessary within 24 hours after making the first request. Within the 24 hour period, if you reuse the same key with different request contents (change the HTTP method, path, or request body), Stedi returns a `422 Unprocessable Entity` error. After 24 hours, Stedi allows the request to execute again even if you submit the same idempotency token.

If you reuse the same key on a new request while the original request is still being processed, Stedi returns a `409 Conflict`. You can retry the request after the original request is completed. The `409` response includes a `Retry-After` header indicating a suggested number of seconds to wait before retrying.

### Generating keys

For APIs that support idempotency, you can generate and include an idempotency key within the `Idempotency-Key` header of your request. Our implementation conforms to the draft IETF [Idempotency-Key HTTP Header Field](https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/) RFC.

The token can be any unique string, such as a UUID. Common approaches to generating tokens are:

* Use an algorithm that generates a token with enough randomness, like UUID v4.
* Derive the key from data related to the API call, like a partnership ID and a transaction number. This approach helps you prevent duplicate requests for the same partnership and request type.

### Adding keys to your request

Once you have generated your idempotency key, include it in the header of your API request. The following example shows the header in a request:

```bash
curl --request POST \
  --url https://core.us.stedi.com/2023-08-01/x12/partnerships/{partnershipId}/generate-edi \
  --header 'Authorization: ${STEDI_API_KEY}' \
  --header 'Idempotency-Key: 5b6f6d3e-2c6d-4e6f-8e6f-6d3e2c6d4e6f' \
  --header 'Content-Type: application/json' \
  --data '{ ... }'
```

## API upgrades

We strive to maintain backwards compatibility. The following changes are considered backwards compatible:

* New API resources
* Additional optional parameters to API requests
* Additional fields in API responses
* Changes in the order of properties in API responses
* Changes in human-readable error messages
* Downgrading mandatory parameters to optional parameters.

When we introduce a breaking change, we release a root-level, dated version.