# Accounts and billing
Source: https://www.stedi.com/docs/accounts-and-billing
***
## title: Accounts and billing
Learn how to manage Stedi accounts, members, billing, and payments.
## Accounts
A Stedi account is a container for all of your Stedi activity and resources. Every account has a unique ID which you can find in the [Account profile](https://portal.stedi.com/app/settings/account-details). This ID is used to identify the account in the API and in the dashboard. It is also used in dashboard URLs, where it appears in the `account` URL parameter.
Accounts can have unlimited members, and members can be [assigned different roles](#assigning-member-roles) with different permissions.
It's possible to have multiple accounts, though using one account is recommended for most customers. If you need additional accounts, you can reach out to [support](https://www.stedi.com/contact) and we'll enable them for you. Note that accounts cannot be linked – all settings and membership are specific to a given account.
You cannot delete an account via the dashboard or the API. If you need to delete an account, first delete all data and resources in the account then [contact support](https://www.stedi.com/contact).
### Settings
To access your user account settings, click your user account icon in the top right of the app. You can set the Stedi app to **Light** or **Dark** mode and enable Multi-Factor Authentication (MFA) for your user account.
To access your Stedi account settings, click the account name and select **Account settings**. You can view the account name, account ID, and require Multi-Factor Authentication (MFA) for all account users.
### Inviting members
You can add members in [member settings](https://portal.stedi.com/app/settings/members). Each time you invite a member, they will receive an email with your invitation. Invitations do not expire, but can be revoked by any account admin at any time before acceptance.
### Removing members
Any account admin can remove other members from an account. Removed users will still retain their Stedi user credentials and access to other accounts of which they're a member.
### Assigning member roles
Admins can use role-based access control (RBAC) to ensure only authorized users can access and modify resources in a Stedi account.
Admins can assign Stedi account members to one of four roles:
* **Admin:** These users can access and modify all resources within a Stedi account. This includes adding and removing members, assigning member roles, adding billing information, configuring settings, running eligibility checks, submitting claims, managing API keys, and configuring resources.
* **Developer:** These users can access and configure all resources, including managing API keys. However, they can't manage members or billing information.
* **Operator:** These users can run eligibility checks, run insurance discovery checks, submit claims, submit transaction enrollments, and review transaction data. They can also manage guides and trading partners (EDI platform). Finally, they can interact with developer resources, but can't modify them. For example, they can call our APIs, but they can't create or delete API keys.
Operator is the minimum required role for a user to interact with our
clearinghouse APIs and review transactions (such as completed eligibility
checks) in Stedi.
* **Read-only:** These users can view some account resources, but cannot modify them. For example, they can review processed transactions in Stedi but can't call APIs.
To change a member's role:
1. Go to [member settings](https://portal.stedi.com/app/settings/members) in your account.
2. Click the pencil icon for a member, choose the appropriate **Role** from the list, and click **Update role**.
### Enabling Multi-Factor Authentication (MFA)
You can enable Multi-Factor Authentication (MFA) for your user account. To enable MFA, click your user account icon in the top right of the app and then click **Enable MFA**.
You can also require **all** users to enable MFA before accessing a Stedi account. To enforce MFA for all users:
1. Click the account name.
2. Select **Account settings** and toggle MFA to **ON**.
The next time a user logs into the Stedi account, Stedi prompts them to set up their MFA token: [https://portal.stedi.com/auth/setup-mfa](https://portal.stedi.com/auth/setup-mfa)
Once you enable MFA for a Stedi account, it cannot be disabled.
## Billing and payment
Each account will be invoiced monthly. To add or edit your payment details, go to your Stedi account, click the account name, and then click **Billing**. Charges will be billed to the credit card on file.
# API Reference
Source: https://www.stedi.com/docs/api-reference
***
title: API Reference
sidebarTitle: "Introduction"
----------------------------
Download our OpenAPI specs
## Clearinghouse APIs
Our APIs allow you to automate business flows like [eligibility checks](/api-reference/healthcare/post-healthcare-eligibility) and [claims processing](/api-reference/healthcare/post-healthcare-claims). We also offer APIs for retrieving [Stedi's up-to-date payer list](/api-reference/healthcare/get-payers) and [provider enrollments](/api-reference/healthcare/post-enrollment-create-provider) with payers.
## EDI platform APIs
You can programmatically accomplish almost anything you can do in Stedi. In practice, most integrations only need to implement two integration points:
* A method in your system for calling the [Create Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint when you need to send a transaction **to** a trading partner
* A method in your system for receiving [destination webhooks](/edi-platform/configure/destinations) from Stedi when you receive a transaction **from** a trading partner, or when an exception occurs.
## 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](/api-reference/healthcare/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.
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.
### API key access
Within your Stedi account, members can be [assigned to roles](/accounts-and-billing#assigning-member-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 '{ ... }'
```
Stedi supports the previous method of prefixing the API key with `Key` (e.g.
`Authorization: Key Jclcke.ZHqS3demo4dS16XZ1KeyBY7`) for
backwards-compatibility.
## 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](/api-reference/edi-platform/core/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.
| Endpoints | Shared pool | Default concurrency limit |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------- |
|
- Real-time eligibility check JSON
- Real-time eligibility check Raw X12
- Real-time claim status JSON
- Real-time claim status Raw X12
| Yes | 50 |
| - Professional claims JSON
- Professional claims Raw X12
- Institutional claims JSON
- Dental claims JSON
- Dental claims Raw X12
- Create claim attachment JSON
- Submit claim attachment JSON
- Submit claim attachment Raw X12
| Yes | 100 |
| - CMS-1500 PDF: Business Identifier
- CMS-1500 PDF: Transaction ID
- 277CA Report
- 835 ERA Report
| Yes | 100 |
| Coordination of Benefits Check | No | 50 |
| Insurance Discovery Check | No | 5 |
| Insurance Discovery Check Results | No | 5 |
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:
```
{
"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. For example, the header for a request to the [Create Outbound Interchange API](/api-reference/edi-platform/post-generate-edi) would look like this:
```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.
# Trust Center
Source: https://www.stedi.com/docs/security-and-compliance/trust-center
***
## title: Trust Center
Visit our [Trust Center](https://trust.stedi.com/) for complete trust and compliance information for all Stedi products and APIs, including our:
* Privacy policy
* Data management policy
* Access control policy
* HIPAA compliance policy
* Certifications, including SOC 2 Type II and HIPAA
* Security and privacy controls
# Batch eligibility checks
Source: https://www.stedi.com/docs/healthcare/batch-refresh-eligibility-checks
***
title: Batch eligibility checks
sidebarTitle: "Batch eligibility checks"
----------------------------------------
Batch eligibility checks are a great option as your volume grows. Stedi handles complexity like queuing and retries according to established best practices, so you don't have to build this logic yourself. We recommend using batch checks for bulk workflows that aren't time sensitive, including:
* Monthly or weekly coverage refreshes
* Upcoming appointments
* Sets of thousands or millions of checks that can run in the background
However, batch checks have a longer feedback cycle than real-time checks because you don't receive the payer's response immediately. That's why we strongly recommend starting with [real-time checks](/api-reference/healthcare/post-healthcare-eligibility) when integrating with a new payer or working with eligibility checks for the first time. This approach allows you to ensure that your pipeline is working smoothly before you begin staging batch checks.
You can submit batch checks manually by uploading CSV files to the Stedi portal or programmatically through the API. Each batch can contain up to 1,000 eligibility checks.
## Transaction enrollment
Some payers require [transaction enrollment](/healthcare/transaction-enrollment) before you can start sending them eligibility checks. The [Payer Network](https://www.stedi.com/healthcare/network) specifies which payers require enrollment.
## Manual submission
To upload a CSV file with batch eligibility checks, go to the [Eligibility check batches](https://portal.stedi.com/app/healthcare/checks/batch) page in the Stedi portal and click **+ New CSV batch**.
### CSV upload
You can download a [template CSV file](/files/batch-eligibility-template.csv) with all of the supported properties.
* Each row in the file corresponds to one batch eligibility check. You can submit up to 1,000 checks per CSV file.
* CSV batch checks support a subset of the properties available in the API. The available properties cover the vast majority of use cases. Contact [Stedi support](https://www.stedi.com/contact) if you need to include additional properties.
Once you upload the CSV file, click **Verify file** so Stedi can validate the data in each eligibility check. You can fix any validation errors and re-upload the CSV file as many times as needed.
When the file is error-free, you'll be able to click **Execute batch** to send the eligibility checks to Stedi. Stedi processes the checks asynchronously, implementing best practices to avoid payer throttling.
### Batch status
The batch status changes to **In progress** while Stedi is processing the batch. The status changes to **Completed** when Stedi has sent all checks in the batch to payers and received responses. A completed batch may contain both successful and failed eligibility checks.
You can [retrieve the results](#retrieve-batch-results) of each check in the batch through the Stedi portal or API.
## API submission
You can use Stedi's [Batch Eligibility Check](/api-reference/healthcare/post-healthcare-batch-eligibility) API to submit up to 1,000 eligibility checks in a single request. Stedi processes these eligibility checks asynchronously, implementing best practices to avoid payer throttling.
### Headers
You must include the following Stedi-specific headers in your API request:
* **`Authorization`:** [Generate an API key](/api-reference#authentication) to use for authentication.
* **`Content-Type`:** Set to `application/json`.
```bash
curl --request POST \
--url https://manager.us.stedi.com/2024-04-01/eligibility-manager/batch-eligibility \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
```
### Request data
The information you provide to the payer in an eligibility check can vary, depending on the circumstances. However, each batch eligibility check must include at least the following information:
| Information | Description |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tradingPartnerServiceId` | - This is the payer ID. Visit the [Payer Network](https://www.stedi.com/healthcare/network) for a complete list. You can send requests using the primary payer ID, the Stedi payer ID, or any alias listed in the payer record.
- If you don't know the payer, try submitting an [insurance discovery check](/healthcare/insurance-discovery) instead.
|
| `submitterTransactionIdentifier` | - A unique identifier for the eligibility check within the batch.
- Stedi returns this identifier in the response for the [Poll Batch Eligibility Checks](/api-reference/healthcare/get-healthcare-polling-eligibility) endpoint so you can correlate eligibility responses with the original eligibility check.
|
| `provider` object, name and identifier | - You must include the provider's name - either the `firstName` and `lastName` of a specific provider within a practice or the `organizationName`.
- You must include an identifier - this is typically the provider's [National Provider Identifier](https://www.stedi.com/docs/healthcare/national-provider-identifier) (`npi`). If the provider doesn't have an NPI, you can supply an alternative, such as their `taxId` or `ssn`.
|
| `subscriber` and/or `dependents` objects | - The `dependents` object is optional - refer to the scenarios when the [patient qualifies as a dependent](/healthcare/send-eligibility-checks#dependents).
- At a minimum, our API requires that you supply at least one of these fields in the request: `memberId`, `dateOfBirth`, or `lastName`. However, each payer has different requirements, so you should supply the fields necessary for each payer to identify the subscriber in their system.
- When all four of `memberId`, `dateOfBirth`, `firstName`, and `lastName` are provided, payers are required to return a response if the member is in their database. Some payers may be able to search with less information, but this varies by payer.
- We recommend always including the patient's member ID when possible. Learn more about [patient information](/healthcare/send-eligibility-checks#patient-information).
|
| `encounter` object, service dates | - You can specify either a single `dateOfService` or a `beginningDateOfService` and `endDateOfService`. The payer defaults to using the current date in their timezone if you don't include one.
- When checking eligibility for today, omit the `dateOfService` property to ensure consistent behavior across payers.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers such as the Centers for Medicare and Medicaid Services (CMS) do support requests for dates further in the future - especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `encounter` object, service or procedure codes | - Specify `serviceTypeCodes` and/or a `procedureCode` and `productOrServiceIDQualifier` to request specific types of benefits information.
- We recommend including no more than one service type code in each request.
- If you don't include any service type code or procedure code information, Stedi defaults to using `30` (Plan coverage and general benefits) as the only `serviceTypeCodes` value.
- Learn more about [STCs and procedure codes](/healthcare/eligibility-stc-procedure-codes).
|
#### Patient information
Batch checks should follow the same best practices as real-time eligibility checks when entering patient information. Visit [Real-time eligibility checks](/healthcare/send-eligibility-checks#patient-information) for guidance on:
* Which patient identifiers to use for best results
* How to know if a patient qualifies as a dependent
* How to enter patient names for best results
#### MBI for CMS checks
A Medicare Beneficiary Identifier (MBI) is a unique, randomly-generated identifier assigned to individuals enrolled in Medicare. You must include the patient's MBI in every eligibility check to the Centers for Medicare and Medicaid Services (payer ID: CMS).
Some payers return the patient's MBI in one of the following properties of the standard eligibility response:
* [`benefitsInformation.benefitsAdditionalInformation.hicNumber`](/api-reference/healthcare/post-healthcare-eligibility#response.benefitsInformation.benefitsAdditionalInformation.hicNumber)
* [`planInformation.hicNumber`](/api-reference/healthcare/post-healthcare-eligibility#response.planInformation.hicNumber)
If the value in either of these properties matches the format specified in the [Medicare Beneficiary Identifier documentation](https://www.cms.gov/training-education/partner-outreach-resources/new-medicare-card/medical-beneficiary-identifiers-mbis), the number is likely an MBI, and we recommend sending a follow-up eligibility check to CMS for additional benefits data. You're most likely to receive an MBI in eligibility check responses from commercial Medicare Advantage plans, but they can also be present in responses from Medicaid plans for dual-eligible patients.
When you don't know a patient's MBI, you can use Stedi's eligibility check APIs to perform an MBI lookup using their Social Security Number instead. Stedi returns a complete benefits response from CMS with the patient's MBI in the `subscriber` object for future reference. Visit [Medicare Beneficiary Identifier (MBI) lookup
](/healthcare/mbi-lookup) for complete details.
**Don't** submit eligibility checks for Medicare Advantage plans to CMS (HETS) - you should submit them to the actual Medicare Advantage plan payer instead.
#### Conditional requirements
Note that objects marked as **required** are required for all requests, while others are conditionally required depending on the circumstances. When you include a conditionally required object, you must include all of its required properties.
For example, you must always include the `provider` object in your request, but you only need to include the `dependents` object when you need to request benefits information for a dependent on the subscriber's insurance plan.
#### Character restrictions
Only use the X12 Basic and Extended character sets in request data. Using characters outside these sets may cause validation and HTTP `400` errors.
The X12 Basic character set includes uppercase letters, digits, space, and some special characters. Lowercase letters and special language characters like `ñ` are not included.
The following special characters are included:

The Extended character set includes the characters listed in Basic, plus lowercase letters and additional special characters, such as `@`.
The following additional special characters are included:

Don't include the following characters in your request data: `~`, `*`, `:` and `^`. They are reserved for delimiters in the resulting X12 EDI transaction, and X12 doesn't support using escape sequences to represent delimiters or special characters. Stedi returns a `400` error if you include these restricted characters in your request.
**Autocorrection for backticks**
Stedi automatically replaces backticks (`` ` ``), also known as backquotes or grave accents, with an apostrophe (`'`) in `subscriber` and `dependents` first and last names. These corrections prevent errors when submitting your request. Stedi returns a message in the response's `warnings` array when it makes this replacement.
### Sample request and response
The following example demonstrates how to submit a batch of eligibility checks in the `items` array, where each item represents an individual eligibility check. Stedi returns a `batchId` that you can use to retrieve the results of these checks later.
Visit [Determine patient benefits](/healthcare/eligibility-active-coverage-benefits) for detailed explanations of how to determine the patient's active coverage, financial responsibility, whether referrals and authorizations are required, and more.
{/* schema:BatchEligibilityChecksRequestContent */}
```bash
curl --request POST \
--url https://manager.us.stedi.com/2024-04-01/eligibility-manager/batch-eligibility \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"items": [
{
"submitterTransactionIdentifier": "ABC123456789",
"tradingPartnerServiceId": "AHS",
"encounter": {
"serviceTypeCodes": [
"MH"
]
},
"provider": {
"organizationName": "ACME Health Services",
"npi": "1999999984"
},
"subscriber": {
"dateOfBirth": "19000101",
"firstName": "Jane",
"lastName": "Doe",
"memberId": "1234567890"
}
},
{
"submitterTransactionIdentifier": "DEF123456799",
"tradingPartnerServiceId": "AHS",
"encounter": {
"serviceTypeCodes": [
"78"
]
},
"provider": {
"organizationName": "ACME Health Services",
"npi": "1999999984"
},
"subscriber": {
"dateOfBirth": "19001021",
"firstName": "John",
"lastName": "Doe",
"memberId": "1234567892"
}
}
]
}'
```
{/* schema:BatchEligibilityChecksResponseContent */}
```json
{
"batchId": "01928d19-df25-76c0-8d51-f5351260fa05",
"submittedAt": "2023-11-07T05:31:56Z"
}
```
### Concurrency limit
Asynchronous batch checks don’t count toward your Stedi account [concurrency limit for real-time checks](/api-reference#concurrency-limits).
There are no limits on the number of batches you can run in parallel.
## Automatic retries
Stedi retries checks that fail due to [payer connectivity issues](/healthcare/eligibility-troubleshooting#payer-connectivity-issues) for up to 8 hours. Therefore, it can take up to 8 hours for all checks in a batch to return results.
## Retrieve batch results
After you've submitted a batch of eligibility checks, you can review and retrieve the results through the Stedi portal or API.
### Stedi portal
You can review the progress of batch eligibility checks submitted manually through CSV files and programmatically through the API on the [Eligibility check batches page](https://portal.stedi.com/app/healthcare/checks/batch).
Click the batch name to view its details, including the status of each check in the batch. You can also download the original CSV input, if the batch was submitted as a CSV file.
On the batch details page, you can click any eligibility check to review it in [Eligibility Manager](/healthcare/eligibility-manager), including the full request and response payload. You'll also be able to edit the request details for failed eligibility checks and resubmit them to the payer.
### Polling endpoint
You can use the [Poll Batch Eligibility Checks](/api-reference/healthcare/get-healthcare-polling-eligibility) endpoint to retrieve the results from batch checks submitted through both the Stedi portal and API.
#### Polling strategy
The response only includes completed checks. As a result, a single polling attempt may not retrieve responses for all checks within the batch.
Most batches complete in 15–30 minutes. However, it can take up to 8 hours for all checks in a batch to return results.
You can start polling immediately. After the initial poll, use exponential backoff with jitter. Start at 2 minutes and approximately double the wait between polls, up to 8 hours. For example, you might use something similar to the following formula (all values in seconds):
```
wait_time = (0 if attempt == 0 else min(120 * 2**(attempt - 1), 8*60*60)) + random(0, 30)
```
In this formula:
* **Immediate first poll:** if `attempt == 0` then wait time is `0`.
* **Start at 2 minutes:** On attempt == `1`, base wait is 120 seconds (2 minutes).
* **Exponential backoff:** Doubles each time: 2, 4, 8, 16, ... minutes.
* **Cap at 8 hours:** min(..., 8*60*60) ensures it never exceeds 480 minutes.
* **Jitter:** Adds a random delay between 0 and 30 seconds.
#### Track completed checks
The polling endpoint only returns completed checks, and Stedi retries checks that fail due to payer connectivity issues for up to 8 hours. You'll need to track the status of pending checks in your own system to determine when to stop polling.
We recommend doing this by either:
* Comparing the total number of checks you sent in the batch with the number of completed checks returned by the polling endpoint.
* Matching the `submitterTransactionIdentifier` of each request to the `submitterTransactionIdentifier` in each response to ensure every check has been processed.
#### Filter results
You can filter the polling results using the following query parameters:
* `batchId`: Retrieve results for a specific batch of eligibility checks. You can find this value in the synchronous response from the [Batch Eligibility Check](/api-reference/healthcare/post-healthcare-batch-eligibility) endpoint.
* `startDateTime`: Retrieve results for checks submitted after a specific date and time (in ISO 8601 format).
The following example example retrieves the results for batch checks submitted after `2025-12-31T00:00:00Z`:
```bash
curl --request GET \
--url https://manager.us.stedi.com/2024-04-01/eligibility-manager/polling/batch-eligibility?startDateTime=2025-12-31T00:00:00Z \
--header 'Authorization: '
```
## Costs
The costs for running a batch eligibility check – manually or using the API – are the same as running the equivalent number of real-time eligibility checks.
For example, if you run a batch with 500 checks, it will cost the same as running 500 real-time eligibility checks.
## Minimize waste
We recommend the following to optimize batch eligibility checks:
* Periodically purge or archive records for inactive patients. It's a waste to perform eligibility checks on patients who have died or who haven't scheduled an encounter for several years.
* Remove or deactivate patients that are no longer eligible. The payer indicates ineligibility by setting `benefitsInformation.code = “6”` (Inactive) in the response.
## Monitor for potential coverage loss
When you receive the results of your batch eligibility checks, look for patients who have coverage that may be at risk.
Check for `benefitsInformation.code = “5”`, which stands for Active - Pending investigation, or a response containing a `benefitsDateInformation.premiumPaidToDateEnd` before the current date. Some payers may still show active coverage while the subscriber is behind on premium payments.
You may want to conduct additional checks on these patients because they have an elevated risk of losing coverage soon.
# Check claim status
Source: https://www.stedi.com/docs/healthcare/check-claim-status
***
title: Check claim status
sidebarTitle: "Check claim status"
----------------------------------
You may need to check the status of a claim when you don't receive a 277CA or 835 ERA response from the payer within your expected timeframe. You may also want to check the status of a claim submitted by another entity. For example, a billing agency may want to check the status of a claim submitted by their customer, who is a provider.
## Manual submission
You can submit a claim status request manually through the [Create claim status check](https://portal.stedi.com/app/healthcare/claims/status/create) form in Stedi.
The response view shows both claim-level and service-level details. If the claim status request returns information for multiple claims, you can use the dropdown to navigate between them.
## API Submission
Call one of the following endpoints to send a 276/277 real-time claim status:
* [Claim Status](/api-reference/healthcare/post-healthcare-claim-status) to send requests in JSON
* [Claim Status Raw X12](/api-reference/healthcare/post-healthcare-claim-status-raw-x12) to send requests in X12 EDI
Both endpoints return a synchronous claim status response from the payer in JSON format. The response may contain information about more than one claim, if the payer has multiple claims on file that match the information you provided.
### Headers
When constructing the request, you must include the following information in HTTP headers:
* **`Authorization`:** [Generate an API key](https://portal.stedi.com/app/settings/api-keys) to use for authentication.
* **`Content-Type`:** Set to `application/json`.
### Body - JSON
For best results, you should start with our [recommended base request](/healthcare/check-claim-status#json-base-request) and add more information only as needed.
Note that objects marked as **required** are required for all requests, while others are conditionally required depending on the circumstances. When you include a conditionally required object, you must include all of its required properties.
For example, you must always include the `subscriber` object in requests, but you only need to include the `serviceLinesInformation` object when you want to request the status for a specific service line.
### Body - X12 EDI
Your payload must conform to [276 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/claim-status-request-x212/01GRYB6A4XEJQ61Y2K2KT606E5).
For best results, you should start with our [recommended base request](/healthcare/check-claim-status#x12-base-request) and add more information only as needed.
#### Envelope and header
Stedi generates its own `ISA` and `GS` headers and `IEA` and `GE` trailers before sending your claim status request to the payer. You can submit your request to Stedi with any values in these segments, as long as they conform to the X12 EDI specification.
However, you must set `ST03` (Version, Release, or Industry Identifier) to `005010X212`.
### Character restrictions
Only use the X12 Basic and Extended character sets in request data. Using characters outside these sets may cause validation and HTTP `400` errors.
The X12 Basic character set includes uppercase letters, digits, space, and some special characters. Lowercase letters and special language characters like `ñ` are not included.
The following special characters are included:

The Extended character set includes the characters listed in Basic, plus lowercase letters and additional special characters, such as `@`.
The following additional special characters are included:

In addition, the following characters are reserved for delimiters in the final X12 EDI transaction to the payer: `~`, `*`, `:`, and `^`. X12 doesn’t support using escape sequences to represent delimiters or special characters. Stedi returns a `400` error if you use these restricted characters improperly.
* **JSON endpoint:** Don’t include delimiter characters anywhere in your request data.
* **Raw X12 endpoint:** You can use these characters as delimiters, but not in the body of the request data.
### Timeout
Requests to payers typically time out at 1 minute, though Stedi can keep connections open longer than that if needed.
### Concurrency limit
Our real-time claim status endpoints share a concurrency pool with other real-time healthcare APIs. For more information, visit [Concurrency Limits](/api-reference#concurrency-limits).
### Recommended API clients
You may want to use an API client to make testing and debugging easier.
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.
Visit [API clients](/api-reference#api-clients) for a list of recommended clients you can use instead.
## Best practices
We recommend following these best practices when sending a 276 real-time claim status request.
### Supply a date of services range
Supply a date range that is at least plus or minus 7 days from the date of the services listed in the claim. The payer may have stored a different date for the encounter than the one in your records, so providing a date range increases the likelihood that the payer will find a match.
We also recommend keeping the dates of service range to 30 days or less. Some payers may reject requests with a date range that is too wide.
### Don't provide too much information
Providing too much information in a 276 real-time claim status request can negatively affect the results. That's why we recommend first sending a base request with only the following information.
You will eventually learn payer-specific nuances and can build logic in your system to supply additional information to specific payers. For example, some payers may have better success rates when you include the claim number.
#### JSON base request
We recommend starting with the following properties in a request to the [Real-Time Claim Status JSON](/api-reference/healthcare/post-healthcare-claim-status) endpoint:
| Information | Description |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tradingPartnerServiceId` | This is the payer ID. Visit the [Payer Network](https://www.stedi.com/healthcare/network) for a complete list. You can send requests using the primary payer ID, the Stedi payer ID, or any payer ID alias listed in the payer record. |
| `providers` | The provider information from the original claim. To start, provide only the `npi`, `organizationName`, and `providerType` properties. |
| `subscriber` | The subscriber information from the original claim. To start, provide only the `firstName`, `lastName`, `dateOfBirth`, `gender`, and `memberId` properties. |
| `dependent` | The dependent information from the original claim. To start, provide only the `firstName`, `lastName`, `dateOfBirth`, and `gender` properties. If the patient is the subscriber, you can omit this object. |
| `encounter` | The encounter information from the original claim. To start, provide only the `beginningDateOfService` and `endDateOfService` properties. Remember that you should provide a date range that is plus or minus 7 days from the date of service listed in the claim for best results. |
If this base request fails to return results, try adding in other information like `encounter.tradingPartnerClaimNumber` and `providers.taxId`.
The following examples show two base request payloads: one where the patient is the subscriber and one where the patient is the dependent. They include only the minimum recommended information:
{/* schema:ClaimStatusRequestContent */}
```json
{
"encounter": {
"beginningDateOfService": "20240318",
"endDateOfService": "20240402"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "Behavioral Services P.C.",
"providerType": "BillingProvider"
}
],
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19000806",
"gender": "F",
"memberId": "111222333"
},
"tradingPartnerServiceId": "3429"
}
```
{/* schema:ClaimStatusRequestContent */}
```json
{
"encounter": {
"beginningDateOfService": "20240318",
"endDateOfService": "20240402"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "Behavioral Services P.C.",
"providerType": "BillingProvider"
}
],
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19000806",
"gender": "F",
"memberId": "111222333"
},
"dependent": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "19100323",
"gender": "M"
},
"tradingPartnerServiceId": "3429"
}
```
#### X12 base request
We recommend starting with the following properties in a request to the [Real-Time Claim Status Raw X12](/api-reference/healthcare/post-healthcare-claim-status-raw-x12) endpoint:
* `Loop 2100A NM109` (Payer Identifier): This identifier allows Stedi to route the claim status request to the correct payer. It must be a payer ID or payer ID alias listed in the [Payer Network](https://www.stedi.com/healthcare/network?page=0). For example, you could use `60054`, `HPQRS`, `AETNA`, or any other listed payer ID alias for Aetna.
* `Loop 2100C NM109` (National Provider Identifier) and `NM103` (Provider Last Name or Organization Name)
* `Loop 2000D DMG02` or `Loop 2000E DMG02` (Subscriber/Patient Birth Date)
* `Loop 2100B NM1` (Information Receiver Name)
* `Loop 2100D NM103` (Subscriber Last Name), `NM103` (Subscriber First Name), and `NM109` (Member Identification Number)
* `Loop 2200D DTP03` (Claim Service Period) that is plus or minus 7 days from the date of service listed in the claim
* `Loop 2200D` or `2200E`: `TRN` (Claim Status Tracking Number)
If this base request fails to return results, try adding in other information like `Loop 2200D REF02` (Payer Claim Control Number).
## Sample requests and responses
The following examples show a 276 claim status request and 277 claim status response for Stedi's JSON endpoint.
### Accepted claims
The following example shows a claim status request and response for a claim that has been accepted by the payer and is awaiting payment. The payer is UnitedHealthcare, and the request uses the payer ID alias `3429`.
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/claimstatus/v2 \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"encounter": {
"beginningDateOfService": "20240318",
"endDateOfService": "20240402"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "Behavioral Services P.C.",
"providerType": "BillingProvider"
}
],
"subscriber": {
"dateOfBirth": "19000806",
"firstName": "Jane",
"lastName": "Doe",
"gender": "F",
"memberId": "111222333"
},
"tradingPartnerServiceId": "3429"
}'
```
{/* schema:ClaimStatusResponseContent */}
```json
{
"claims": [
{
"claimStatus": {
"amountPaid": "95.55",
"claimServiceDate": "20240325",
"effectiveDate": "20240329",
"paidDate": "20240329",
"patientAccountNumber": "3333333",
"statusCategoryCode": "P5",
"statusCategoryCodeValue": "Pending/Payer Administrative/System hold",
"statusCode": "3",
"statusCodeValue": "Claim has been adjudicated and is awaiting payment cycle.",
"submittedAmount": "238.44",
"trackingNumber": "222222222",
"tradingPartnerClaimNumber": "5332034153-KK"
},
"serviceDetails": [
{
"service": {
"amountPaid": "95.55",
"procedureId": "90837",
"serviceIdQualifier": "Health Care Financing Administration Common Procedural Coding System (HCPCS) Codes",
"serviceIdQualifierCode": "HC",
"submittedAmount": "238.44",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20240329",
"statusCategoryCode": "P5",
"statusCategoryCodeValue": "Pending/Payer Administrative/System hold",
"statusCode": "3",
"statusCodeValue": "Claim has been adjudicated and is awaiting payment cycle."
}
]
}
]
}
],
"controlNumber": "222222222",
"meta": {
"applicationMode": "production",
"traceId": "bf27223e-46c3-451e-b2b4-46f3f0b6fe3b"
},
"payer": {
"organizationName": "UNITEDHEALTHCARE",
"payerIdentification": "3429"
},
"providers": [
{
"organizationName": "Behavioral Services P.C.",
"providerType": "BillingProvider",
"taxId": "123456789"
},
{
"npi": "1999999984",
"organizationName": "Behavioral Services P.C.",
"providerType": "ServiceProvider"
}
],
"reassociationKey": "000000001",
"status": "success",
"subscriber": {
"firstName": "JANE",
"lastName": "DOE",
"memberId": "111222333"
},
"tradingPartnerServiceId": "3429",
"x12": "..."
}
```
The following example shows a claim status request and response for a claim that has been processed and paid. The payer is UnitedHealthcare, and the request uses the primary payer ID `87726`.
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/claimstatus/v2 \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"providers": [
{
"organizationName": "Provider Name",
"npi": "1999999984",
"providerType": "BillingProvider"
}
],
"subscriber": {
"memberId": "UHC123456",
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19710101"
},
"encounter": {
"beginningDateOfService": "20250630",
"endDateOfService": "20250702"
}
}'
```
{/* schema:ClaimStatusResponseContent */}
```json
{
"claims": [
{
"claimStatus": {
"amountPaid": "108.77",
"checkIssueDate": "20250717",
"checkNumber": "A123456789",
"claimServiceDate": "20250701",
"effectiveDate": "20250717",
"paidDate": "20250715",
"patientAccountNumber": "12345678",
"statusCategoryCode": "F1",
"statusCategoryCodeValue": "Finalized/Payment - The claim/line has been paid.",
"statusCode": "65",
"statusCodeValue": "Claim/line has been paid.",
"submittedAmount": "267.54",
"trackingNumber": "0123456789",
"tradingPartnerClaimNumber": "0123456789"
},
"serviceDetails": [
{
"service": {
"amountPaid": "108.77",
"procedureId": "90837",
"serviceIdQualifier": "Health Care Financing Administration Common Procedural Coding System (HCPCS) Codes",
"serviceIdQualifierCode": "HC",
"submittedAmount": "267.54",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20250717",
"statusCategoryCode": "F1",
"statusCategoryCodeValue": "Finalized/Payment - The claim/line has been paid.",
"statusCode": "107",
"statusCodeValue": "Processed according to contract provisions (Contract refers to provisions that exist between the Health Plan and a Provider of Health Care Services)."
}
]
}
]
}
],
"controlNumber": "123456789",
"payer": {
"organizationName": "UNITEDHEALTHCARE",
"payerIdentification": "87726"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "Provider Name",
"providerType": "BillingProvider"
}
],
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"memberId": "UHC123456"
},
"tradingPartnerServiceId": "87726",
"x12": "ISA*00* *00* *ZZ*STEDI *01*117151744 *250912*1718*^*00501*123456789*0*P*:~GS*HN*STEDI*117151744*20250912*171842*1*X*005010X212~ST*277*1001*005010X212~BHT*0010*08*0123456789*20250912*171841*DG~HL*1**20*1~NM1*PR*2*UNITEDHEALTHCARE*****PI*87726~HL*2*1*21*1~NM1*41*2*PROVIDER NAME*****46*1234567890~HL*3*2*19*1~NM1*1P*2*PROVIDER NAME*****XX*1999999984~HL*4*3*22*0~NM1*IL*1*DOE*JANE****MI*UHC123456~TRN*2*0123456789~STC*F1:65*20250717**267.54*108.77*20250715**20250717*123456789~REF*1K*0123456789~REF*EJ*12345678~DTP*472*D8*20250701~SVC*HC:90837:GT*267.54*108.77****1~STC*F1:107*20250717~DTP*472*D8*20250701~SE*19*1001~GE*1*1~IEA*1*123456789~"
}
```
### Denied claims
The following example shows a claim status request and response for a denied claim. The payer is Anthem Blue Cross Blue Shield of Virginia, and the request uses the primary payer ID `423`.
In this example, the `subscriber` in the request is actually a dependent using the subscriber's member ID.
```bash
curl --request POST \
--url "https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/claimstatus/v2" \
--header "Authorization: " \
--header "Content-Type: application/json" \
--data '{
"encounter": {
"beginningDateOfService": "20241101",
"endDateOfService": "20241112"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "PROVIDER NAME",
"providerType": "BillingProvider"
}
],
"subscriber": {
"dateOfBirth": "19800101",
"firstName": "JANE",
"lastName": "DOE",
"memberId": "XYZO9NUSPD6R"
},
"tradingPartnerServiceId": "423"
}'
```
{/* schema:ClaimStatusResponseContent */}
```json
{
"claims": [
{
"claimStatus": {
"amountPaid": "0",
"claimServiceDate": "20241107-20241107",
"effectiveDate": "20241110",
"paidDate": "20241110",
"patientAccountNumber": "12345678",
"statusCategoryCode": "F0",
"statusCategoryCodeValue": "Finalized - The claim/encounter has completed the adjudication cycle and no more action will be taken.",
"statusCode": "1",
"statusCodeValue": "For more detailed information,see remittance advice.",
"submittedAmount": "200.02",
"trackingNumber": "VZYTLPWDTPMIG66PX0GRNPFGR8",
"tradingPartnerClaimNumber": "XP5BPO2GRUVIR"
},
"serviceDetails": [
{
"service": {
"amountPaid": "0",
"procedureId": "90800",
"serviceIdQualifier": "Health Care Financing Administration Common Procedural Coding System (HCPCS) Codes",
"serviceIdQualifierCode": "HC",
"submittedAmount": "200.02",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20241110",
"statusCategoryCode": "F2",
"statusCategoryCodeValue": "Finalized/Denial - The claim/line has been denied.",
"statusCode": "585",
"statusCodeValue": "Denied Charge or Non-covered Charge."
}
]
}
]
}
],
"controlNumber": "987654321",
"dependent": {
"firstName": "JANE",
"lastName": "DOE"
},
"payer": {
"organizationName": "ANTHEM BLUE CROSS BLUE SHIELD",
"payerIdentification": "423"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "PROVIDER NAME",
"providerType": "BillingProvider"
}
],
"subscriber": {
"firstName": "JOHN",
"lastName": "DOE",
"memberId": "XYZO9NUSPD6R"
},
"tradingPartnerServiceId": "423",
"x12": "..."
}
```
The following examples show a request and response for a denied claim. The payer is Aetna, and the request uses the primary payer ID `60054`.
In this example, the claim is for a dependent.
```bash
curl --request POST \
--url "https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/claimstatus/v2" \
--header "Authorization: " \
--header "Content-Type: application/json" \
--data '{
"dependent": {
"dateOfBirth": "20010714",
"firstName": "JORDAN",
"lastName": "DOE"
},
"encounter": {
"beginningDateOfService": "20250804",
"endDateOfService": "20250806"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "Provider Name",
"providerType": "BillingProvider"
}
],
"subscriber": {
"dateOfBirth": "19710101",
"firstName": "JANE ",
"lastName": "DOE",
"memberId": "AETNA12345"
},
"tradingPartnerName": "Aetna",
"tradingPartnerServiceId": "60054"
}'
```
{/* schema:ClaimStatusResponseContent */}
```json
{
"claims": [
{
"claimStatus": {
"amountPaid": "0",
"checkIssueDate": "20250814",
"checkNumber": "123456789",
"claimServiceDate": "20250805",
"effectiveDate": "20250912",
"paidDate": "20250809",
"patientAccountNumber": "123456789",
"statusCategoryCode": "F2",
"statusCategoryCodeValue": "Finalized/Denial - The claim/line has been denied.",
"statusCode": "585",
"statusCodeValue": "Denied Charge or Non-covered Charge.",
"submittedAmount": "1101",
"trackingNumber": "123456789",
"tradingPartnerClaimNumber": "123456789"
},
"serviceDetails": [
{
"service": {
"amountPaid": "0",
"procedureId": "D1120",
"serviceIdQualifier": "American Dental Association Codes",
"serviceIdQualifierCode": "AD",
"submittedAmount": "141",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20250912",
"statusCategoryCode": "F2",
"statusCategoryCodeValue": "Finalized/Denial - The claim/line has been denied.",
"statusCode": "585",
"statusCodeValue": "Denied Charge or Non-covered Charge."
}
]
},
{
"service": {
"amountPaid": "0",
"procedureId": "D0801",
"serviceIdQualifier": "American Dental Association Codes",
"serviceIdQualifierCode": "AD",
"submittedAmount": "274",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20250912",
"statusCategoryCode": "F2",
"statusCategoryCodeValue": "Finalized/Denial - The claim/line has been denied.",
"statusCode": "585",
"statusCodeValue": "Denied Charge or Non-covered Charge."
}
]
},
{
"service": {
"amountPaid": "0",
"procedureId": "D0603",
"serviceIdQualifier": "American Dental Association Codes",
"serviceIdQualifierCode": "AD",
"submittedAmount": "161",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20250912",
"statusCategoryCode": "F2",
"statusCategoryCodeValue": "Finalized/Denial - The claim/line has been denied.",
"statusCode": "107",
"statusCodeValue": "Processed according to contract provisions (Contract refers to provisions that exist between the Health Plan and a Provider of Health Care Services)."
}
]
},
{
"service": {
"amountPaid": "0",
"procedureId": "D0350",
"serviceIdQualifier": "American Dental Association Codes",
"serviceIdQualifierCode": "AD",
"submittedAmount": "145",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20250912",
"statusCategoryCode": "F2",
"statusCategoryCodeValue": "Finalized/Denial - The claim/line has been denied.",
"statusCode": "585",
"statusCodeValue": "Denied Charge or Non-covered Charge."
}
]
},
{
"service": {
"amountPaid": "0",
"procedureId": "D0350",
"serviceIdQualifier": "American Dental Association Codes",
"serviceIdQualifierCode": "AD",
"submittedAmount": "145",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20250912",
"statusCategoryCode": "F2",
"statusCategoryCodeValue": "Finalized/Denial - The claim/line has been denied.",
"statusCode": "585",
"statusCodeValue": "Denied Charge or Non-covered Charge."
}
]
},
{
"service": {
"amountPaid": "0",
"procedureId": "D0330",
"serviceIdQualifier": "American Dental Association Codes",
"serviceIdQualifierCode": "AD",
"submittedAmount": "235",
"submittedUnits": "1"
},
"status": [
{
"effectiveDate": "20250912",
"statusCategoryCode": "F2",
"statusCategoryCodeValue": "Finalized/Denial - The claim/line has been denied.",
"statusCode": "585",
"statusCodeValue": "Denied Charge or Non-covered Charge."
}
]
}
]
}],
"controlNumber": "123456789",
"dependent": {
"firstName": "JORDAN",
"lastName": "DOE"
},
"payer": {
"organizationName": "AETNA",
"payerIdentification": "60054"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "Provider Name",
"providerType": "BillingProvider"
}
],
"subscriber": {
"firstName": "JANE",
"lastName": "DOE",
"memberId": "AETNA12345"
},
"tradingPartnerServiceId": "60054",
"x12": "ISA*00* *00* *ZZ*STEDI *01*117151744 *250911*1726*^*00501*123456789*0*P*:~GS*HN*STEDI*117151744*20250911*1226*123456789*X*005010X212~ST*277*123456789*005010X212~BHT*0010*08*1234567890*20250911*13263006*DG~HL*1**20*1~NM1*PR*2*AETNA*****PI*60054~PER*IC*Aetna*TE*1234567890~HL*2*1*21*1~NM1*41*2*PROVIDER NAME*****46*1234567890~HL*3*2*19*1~NM1*1P*2*PROVIDER NAME*****XX*1999999984~HL*4*3*22*1~NM1*IL*1*DOE*JANE****MI*AETNA12345~HL*5*4*23~NM1*QC*1*DOE*JORDAN~TRN*2*123456789~STC*F2:585*20250911**1101*0*20250809**20250814*123456789*F2:107~REF*1K*123456789~REF*EJ*123456789~DTP*472*D8*20250805~SVC*AD:D1120*141*0****1~STC*F2:585*20250911~DTP*472*D8*20250805~SVC*AD:D0801*274*0****1~STC*F2:585*20250911~DTP*472*D8*20250805~SVC*AD:D0603*161*0****1~STC*F2:107*20250911********F2:735~DTP*472*D8*20250805~SVC*AD:D0350*145*0****1~STC*F2:585*20250911~DTP*472*D8*20250805~SVC*AD:D0350*145*0****1~STC*F2:585*20250911~DTP*472*D8*20250805~SE*34*123456789~GE*1*123456789~IEA*1*123456789~"
}
```
### No matches found
The following example shows a request and response for a claim status check that failed because the payer couldn't find a matching claim. The payer is Cigna, and the request uses the payer ID alias `CIGNA`.
```bash
curl --request POST \
--url "https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/claimstatus/v2" \
--header "Authorization: " \
--header "Content-Type: application/json" \
--data '{
"encounter": {
"beginningDateOfService": "20250526",
"endDateOfService": "20250601"
},
"providers": [
{
"organizationName": "Provider Name",
"providerType": "BillingProvider",
"npi": "1999999984"
}
],
"subscriber": {
"dateOfBirth": "19910202",
"firstName": "James",
"lastName": "Jones",
"memberId": "CIGNA12345"
},
"tradingPartnerServiceId": "CIGNA"
}'
```
{/* schema:ClaimStatusResponseContent */}
```json
{
"claims": [
{
"claimStatus": {
"amountPaid": "0",
"claimServiceDate": "20250526-20250601",
"effectiveDate": "20250912",
"entity": "Insurer",
"entityCode": "IN",
"statusCategoryCode": "D0",
"statusCategoryCodeValue": "Data Search Unsuccessful - The payer is unable to return status on the requested claim(s) based on the submitted search criteria.",
"statusCode": "97",
"statusCodeValue": "Patient eligibility not found with entity.",
"submittedAmount": "0",
"trackingNumber": "123456789"
}
}
],
"controlNumber": "123456789",
"payer": {
"organizationName": "CHLIC",
"payerIdentification": "CIGNA"
},
"providers": [
{
"npi": "1999999984",
"organizationName": "Provider Name",
"providerType": "BillingProvider"
}
],
"subscriber": {
"firstName": "JAMES",
"lastName": "JONES",
"memberId": "CIGNA12345"
},
"tradingPartnerServiceId": "CIGNA",
"x12": "ISA*00* *00* *ZZ*STEDI *01*117151744 *250825*2004*^*00501*123456789*0*P*:~GS*HN*STEDI*117151744*20250825*1504*123456789*X*005010X212~ST*277*123456789*005010X212~BHT*0010*08*123456789*20250825*160450*DG~HL*1**20*1~NM1*PR*2*CHLIC*****PI*CIGNA~PER*IC*CHC Medical*TE*8002725713~HL*2*1*21*1~NM1*41*2*PROVIDER NAME*****46*123456789~HL*3*2*19*1~NM1*1P*2*PROVIDER NAME*****XX*1999999984~HL*4*3*22*0~NM1*IL*1*JONES*JAMES****MI*CIGNA12345~TRN*2*123456789~STC*D0:97:IN*20250825**0*0~DTP*472*RD8*20250526-20250601~SE*15*123456789~GE*1*123456789~IEA*1*123456789~"
}
```
## Claims submitted by other providers
You likely won't be able to check the status of a claim submitted by a different provider organization or by the patient themselves, even if you have all of the details about the claim.
Payers generally only allow a provider organization to check the status of the claims they submitted. They impose these access controls to protect plan member privacy and confidential commercial data.
## Claims older than 18 months
Payers often archive claims older than 18 months, but this varies by payer. If you try to check the status of a claim from several years ago, the payer may return an error even if the information you submit matches a real historical claim.
## Billing for claim status
We don't bill you for API calls that return 4xx or 5xx errors. For example, you won't be charged when a request fails because the payer isn't supported - in this case, Stedi returns a `400` HTTP status code.
All other transactions are billed at the usage rates according to your contract.
## Code lists
You may need to reference the following code lists when working with the claim status request or response.
### Claim status
Used in the `claims.claimStatus.statusCode` property. This is the status code used to identify the status of an entire claim or a service line. For example, code `20` means `Accepted for Processing`.
This is either a Health Care Claim Status Code or a National Council for Prescription Drug Programs (NCPDP) Reject/Payment Code, when the status is related to pharmacy claims.
* Visit [Claim Status Codes](https://x12.org/codes/claim-status-codes) in the official X12 documentation for a complete list of Health Care Claim Status Codes.
* Visit the [National Council for Prescription Drug Programs website](https://www.ncpdp.org/) for access to the Reject/Payment Code list.
### Claim status category
Used in the `claims.claimStatus.statusCategoryCode` property. For example, code `F1` means `Finalized/Revised - Adjudication information has been changed`.
Visit [Claim Status Category Codes](https://x12.org/codes/claim-status-category-codes) in the official X12 documentation for a complete list.
### Product or service ID qualifier
Used in the `serviceLineInformation.productOrServiceIDQualifier` request property and the `claims.serviceDetails.service.serviceIdQualifierCode` property in the response.
| Code | Description | Usage Notes |
| ---- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `AD` | American Dental Association Codes | - |
| `ER` | Jurisdiction Specific Procedure and Supply Codes | This code is not allowed for use under HIPAA. The qualifier can only be used when 1) If a new rule names the Jurisdiction Specific Procedure and Supply Codes as an allowable code set under HIPAA, OR 2) The Secretary grants an exception to use the code set as a pilot project as allowed under the law, OR 3) For claims that aren't covered under HIPAA. |
| `HC` | Health Care Financing Administration Common Procedural Coding System (HCPCS) Codes | Because the CPT codes of the American Medical Association are also level 1 HCPCS codes, the CPT codes are reported under the code HC. |
| `HP` | Health Insurance Prospective Payment System (HIPPS) Skilled Nursing Facility Rate Code | - |
| `IV` | Home Infusion EDI Coalition (HIEC) Product/Service Code | This code is not allowed for use under HIPAA. The qualifier can only be used when 1) If a new rule names the Home Infusion EDI Coalition Codes as an allowable code set under HIPAA, OR 2) The Secretary grants an exception to use the code set as a pilot project as allowed under the law, OR 3) For claims that aren't covered under HIPAA. |
| `N4` | National Drug Code in 5-4-2 Format | - |
| `NU` | National Uniform Billing Committee (NUBC) UB92 Codes | This code is the NUBC Revenue Code. |
| `WK` | Advanced Billing Concepts (ABC) Codes | This code set has been approved by the Secretary of HHS as a pilot project allowed under HIPAA law. The qualifier may only be used in transactions covered under HIPAA; by parties registered in the pilot project and their trading partners, OR when a new rule names the Complementary, Alternative, or Holistic Procedure Codes as an allowable code set under HIPAA, OR for claims that aren't covered under HIPAA. |
# Claims code lists
Source: https://www.stedi.com/docs/healthcare/claims-code-lists
***
title: Claims code lists
sidebarTitle: 'Code lists'
--------------------------
You may need to reference the following code lists when submitting professional, dental, and institutional claims. Note that this page doesn't contain every code list in the claim specifications; it only contains code lists that are too long to represent clearly within the [API reference documentation](https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-claims).
## Ambulance Certification Condition Codes
Used in the professional claims `claimInformation.ambulanceCertification.conditionCodes` property.
* `01` - Patient was admitted to a hospital
* `04` - Patient was moved by stretcher
* `05` - Patient was unconscious or in shock
* `06` - Patient was transported in an emergency situation
* `07` - Patient had to be physically restrained
* `08` - Patient had visible hemorrhaging
* `09` - Ambulance service was medically necessary
* `12` - Patient is confined to a bed or chair; use to indicate that the patient was bedridden during transport
## Ambulance Transport Reason Codes
Used in the professional claims `claimInformation.ambulanceTransportInformation.ambulanceTransportReasonCode` property.
* `A` - Patient was transported to nearest facility for care of symptoms, complaints, or both
* `B` - Patient was transported for the benefit of a preferred physician
* `C` - Patient was transported for the nearness of family members
* `D` - Patient was transported for the care of a specialist or for availability of specialized equipment
* `E` - Patient Transferred to Rehabilitation Facility
## Attachment Report Type Codes
Used in the following APIs and properties:
* Professional claims `claimInformation.serviceLines.serviceLineSupplementalInformation.attachmentReportTypeCode` property
* Institutional claims `claimInformation.claimSupplementalInformation.reportInformation.attachmentReportTypeCode` property
* Dental claims `claimInformation.claimSupplementalInformation.reportInformation.attachmentReportTypeCode` property. A subset of the codes are supported for [dental claims](#dental).
You can use the following codes:
* `03` - Report Justifying Treatment Beyond Utilization Guidelines
* `04` - Drugs Administered
* `05` - Treatment Diagnosis
* `06` - Initial Assessment
* `07` - Functional Goals
* `08` - Plan of Treatment
* `09` - Progress Report
* `10` - Continued Treatment
* `11` - Chemical Analysis
* `13` - Certified Test Report
* `15` - Justification for Admission
* `21` - Recovery Plan
* `A3` - Allergies/Sensitivities Document
* `A4` - Autopsy Report
* `AM` - Ambulance Certification
* `AS` - Admission Summary
* `B2` - Prescription
* `B3` - Physician Order
* `B4` - Referral Form
* `BR` - Benchmark Testing Results
* `BS` - Baseline
* `BT` - Blanket Test Results
* `CB` - Chiropractic Justification
* `CK` - Consent Form(s)
* `CT` - Certification
* `D2` - Drug Profile Document
* `DA` - Dental Models
* `DB` - Durable Medical Equipment Prescription
* `DG` - Diagnostic Report
* `DJ` - Discharge Monitoring Report
* `DS` - Discharge Summary
* `EB` - Explanation of Benefits (Coordination of Benefits or Medicare Secondary Payor)
* `HC` - Health Certificate
* `HR` - Health Clinic Records
* `I5` - Immunization Record
* `IR` - State School Immunization Records
* `LA` - Laboratory Results
* `M1` - Medical Record Attachment
* `MT` - Models
* `NN` - Nursing Notes
* `OB` - Operative Note
* `OC` - Oxygen Content Averaging Report
* `OD` - Orders and Treatments Document
* `OE` - Objective Physical Examination (including vital signs) Document
* `OX` - Oxygen Therapy Certification
* `OZ` - Support Data for Claim
* `P4` - Pathology Report
* `P5` - Patient Medical History Document
* `PE` - Parenteral or Enteral Certification
* `PN` - Physical Therapy Notes
* `PO` - Prosthetics or Orthotic Certification
* `PQ` - Paramedical Results
* `PY` - Physician's Report
* `PZ` - Physical Therapy Certification
* `RB` - Radiology Films
* `RR` - Radiology Reports
* `RT` - Report of Tests and Analysis Report
* `RX` - Renewable Oxygen Content Averaging Report
* `SG` - Symptoms Document
* `V5` - Death Notification
* `XP` - Photographs
### Dental
For dental claims, only the following attachment report type codes are supported:
* `B4` - Referral Form
* `DA` - Dental Models
* `DG` - Diagnostic Report
* `EB` - Explanation of Benefits (Coordination of Benefits or Medicare Secondary Payor)
* `OZ` - Support Data for Claim
* `P6` - Periodontal Charts
* `RB` - Radiology Films
* `RR` - Radiology Reports
## Attachment Transmission Codes
Used in the professional claims `claimInformation.serviceLines.durableMedicalEquipmentCertificateOfMedicalNecessity.attachmentTransmissionCode` property.
* `AB` - Previously Submitted to Payer
* `AD` - Certification Included in this Claim
* `AF` - Narrative Segment Included in this Claim
* `AG` - No Documentation is Required
* `NS` - Not Specified; Paperwork is available on request at the provider's site. This means that the paperwork is not being sent with the claim at this time. Instead, it is available to the payer (or appropriate entity) at their request.
## Claim Filing Indicator Codes
Used in the following APIs and properties:
* Professional Claims `claimInformation.claimFilingCode` and `claimInformation.otherSubscriberInformation.claimFilingIndicatorCode` properties.
* Institutional Claims `claimInformation.claimFilingCode` and `claimInformation.otherSubscriberInformation.claimFilingIndicatorCode` properties.
* Dental Claims `claimInformation.claimFilingCode` and `claimInformation.otherSubscriberInformation.claimFilingIndicatorCode` properties.
You can use the following codes:
* `11` - Other Non-Federal Programs
* `12` - Preferred Provider Organization (PPO)
* `13` - Point of Service (POS)
* `14` - Exclusive Provider Organization (EPO)
* `15` - Indemnity Insurance
* `16` - Health Maintenance Organization (HMO) Medicare Risk
* `17` - Dental Maintenance Organization
* `AM` - Automobile Medical
* `BL` - Blue Cross/Blue Shield
* `CH` - Champus
* `CI` - Commercial Insurance Co.
* `DS` - Disability
* `FI` - Federal Employees Program
* `HM` - Health Maintenance Organization
* `LM` - Liability Medical
* `MA` - Medicare Part A
* `MB` - Medicare Part B
* `MC` - Medicaid
* `OF` - Other Federal Program; Use when submitting Medicare Part D claims
* `TV` - Title V
* `VA` - Veterans Affairs Plan
* `WC` - Workers' Compensation Health Claim
* `ZZ` - Mutually Defined; Use when Type of Insurance is not known
### Choosing the right code
For some payers, the value for `claimInformation.claimFilingCode` is relatively obvious. For example, if you're submitting a claim to Medicaid California Medi-Cal, then it makes sense to default to populating `claimInformation.claimFilingCode` with `MC` (Medicaid).
For other payers, the correct code may be more difficult to determine. For example, if submitting a claim to the Centers for Medicare and Medicaid Services (CMS), you may need to submit `MA` (Medicare Part A) or `MB` (Medicare Part B).
In these cases, you can run a [real-time eligibility check](/healthcare/send-eligibility-checks) and evaluate whether the response contains any information that clearly suggests which claim filing code to use. For example, if the eligibility response contains `"benefitsInformation.insuranceType" : "Commercial"` then you should submit `"claimInformation.claimFilingCode": "CI"`.
One thing to note is that you may not always get back a `benefitsInformation.insuranceType` value in an eligibility response because payers are not required to send it. In these cases, you can just submit `ZZ` as the `claimFilingCode` because the vast majority of payers will accept that value.
Once you use this workflow to determine a best guess for the Claim Filing Indicator Code for each payer, you can try sending a claim.
* **Rejection:** The rejection message will clearly state that the claim filing indicator code was incorrect, and should state which one to send instead.
* **Acceptance:** The claim filing indicator code you submitted was correct.
## Claim Pricing (Institutional Claims)
For properties in the Institutional Claims `claimInformation.claimPricingInformation` object and the `claimInformation.serviceLines.lineAdjudicationInformation` object.
### Exception Codes
Used in the institutional claims `claimInformation.claimPricingInformation.exceptionCode` property.
* `1` - Non-Network Professional Provider in Network Hospital
* `2` - Emergency Care
* `3` - Services or Specialist not in Network
* `4` - Out-of-Service Area
* `5` - State Mandates
* `6` - Other
### Policy Compliance Codes
Used in the institutional claims `claimInformation.claimPricingInformation.policyComplianceCode` and `claimInformation.serviceLines.linePricingInformation.policyComplianceCode` properties.
* `1` - Procedure Followed (Compliance)
* `2` - Not Followed - Call Not Made (Non-Compliance Call Not Made)
* `3` - Not Medically Necessary (Non-Compliance Non-Medically Necessary)
* `4` - Not Followed Other (Non-Compliance Other)
* `5` - Emergency Admit to Non-Network Hospital
### Pricing Methodology Codes
Used in the institutional claims `claimInformation.claimPricingInformation.pricingMethodologyCode` and `claimInformation.serviceLines.lineRepricingInformation.pricingMethodologyCode` properties.
* `00` - Zero Pricing (Not Covered Under Contract)
* `01` - Priced as Billed at 100%
* `02` - Priced at the Standard Fee Schedule
* `03` - Priced at a Contractual Percentage
* `04` - Bundled Pricing
* `05` - Peer Review Pricing
* `06` - Per Diem Pricing
* `07` - Flat Rate Pricing
* `08` - Combination Pricing
* `09` - Maternity Pricing
* `10` - Other Pricing
* `11` - Lower of Cost
* `12` - Ratio of Cost
* `13` - Cost Reimbursed
* `14` - Adjustment Pricing
### Product or Service ID Qualifier Codes
Used in the institutional claims properties:
* `claimInformation.claimPricingInformation.productOrServiceIDQualifier`
* `claimInformation.serviceLines.lineAdjudicationInformation.productOrServiceIDQualifier`
* `claimInformation.serviceLines.institutionalService.procedureIdentifier`
* `claimInformation.serviceLines.lineRepricingInformation.productOrServiceIDQualifier`
* `ER` - Jurisdiction Specific Procedure and Supply Codes; Not allowed for use under HIPAA. You can only use this code if a new rule names the Jurisdiction Specific Procedure and Supply Codes as an allowable code set under HIPAA, OR the Secretary grants an exception to use the code set as a pilot project as allowed under the law, OR for claims not covered by HIPAA.
* `HC` - Health Care Financing Administration Common Procedural Coding System (HCPCS) Codes; Because the AMA's CPT codes are also level 1 HCPCS codes, they are reported under HC.
* `HP` - Health Insurance Prospective Payment System (HIPPS) Skilled Nursing Facility Rate Code
* `IV` - Home Infusion EDI Coalition (HIEC) Product/Service Code; Not allowed for use under HIPAA. You can only use this qualifier if a new rule names the Home Infusion EDI Coalition (HIEC) Product/Service Codes as an allowable code set under HIPAA, OR the Secretary grants an exception to use the code set as a pilot project as allowed under the law, OR for claims not covered by HIPAA.
* `WK` - Advanced Billing Concepts (ABC) Codes; Approved by the Secretary of HHS as a pilot project allowed under HIPAA law. Only parties registered in the pilot project and their trading partners can use this qualifier in transactions covered by HIPAA. Otherwise, you can only use this code if a new rule names the Complementary, Alternative, or Holistic Procedure Codes as an allowable code set under HIPAA OR for claims not covered by HIPAA.
### Reject Reason Codes
Used in the institutional claims `claimInformation.claimPricingInformation.rejectReasonCode` and `claimInformation.serviceLines.lineRepricingInformation.rejectReasonCode` properties.
* `T1` - Cannot Identify Provider as TPO (Third Party Organization) Participant
* `T2` - Cannot Identify Payer as TPO (Third Party Organization) Participant
* `T3` - Cannot Identify Insured as TPO (Third Party Organization) Participant
* `T4` - Payer Name or Identifier Missing
* `T5` - Certification Information Missing
* `T6` - Claim does not contain enough information for re-pricing
## Composite Medical Procedure - Product or Service ID Qualifier Codes
Used in the professional claims `claimInformation.serviceLines.lineAdjudicationInformation.serviceIdQualifier` and `claimInformation.serviceLines.professionalService.procedureIdentifier` properties.
* `ER` - Jurisdiction Specific Procedure and Supply Codes; Not allowed for use under HIPAA. You can only use this code if a new rule names the Jurisdiction Specific Procedure and Supply Codes as an allowable code set under HIPAA, OR the Secretary grants an exception to use the code set as a pilot project as allowed under the law, OR for claims not covered by HIPAA.
* `HC` - Health Care Financing Administration Common Procedural Coding System (HCPCS) Codes; Because the AMA's CPT codes are also level 1 HCPCS codes, they are reported under HC.
* `IV` - Home Infusion EDI Coalition (HIEC) Product/Service Code; Not allowed for use under HIPAA. You can only use this qualifier if a new rule names the Home Infusion EDI Coalition (HIEC) Product/Service Codes as an allowable code set under HIPAA, OR the Secretary grants an exception to use the code set as a pilot project as allowed under the law, OR for claims not covered by HIPAA.
* `WK` - Advanced Billing Concepts (ABC) Codes; Approved by the Secretary of HHS as a pilot project allowed under HIPAA law. Only parties registered in the pilot project and their trading partners can use this qualifier in transactions covered by HIPAA. Otherwise, you can only use this code if a new rule names the Complementary, Alternative, or Holistic Procedure Codes as an allowable code set under HIPAA OR for claims not covered by HIPAA.
## Delay Reason Codes
Used in the following APIs and properties:
* Professional claims `claimInformation.delayReasonCode` property.
* Institutional claims `claimInformation.delayReasonCode` property.
* Dental claims `claimInformation.delayReasonCode` property.
You can use the following codes:
* `1` - Proof of Eligibility Unknown or Unavailable
* `2` - Litigation
* `3` - Authorization Delays
* `4` - Delay in Certifying Provider
* `5` - Delay in Supplying Billing Forms
* `6` - Delay in Delivery of Custom-made Appliances
* `7` - Third Party Processing Delay
* `8` - Delay in Eligibility Determination
* `9` - Original Claim Rejected or Denied Due to a Reason Unrelated to the Billing Limitation Rules
* `10` - Administration Delay in the Prior Approval Process
* `11` - Other
* `15` - Natural Disaster
## Drug Identification Product or Service ID Qualifier Codes
Used in the professional claims `claimInformation.serviceLines.drugIdentification.serviceIdQualifier` property.
* `EN` - EAN/UCC - 13
* `EO` - EAN/UCC - 8
* `HI` - HIBC (Health Care Industry Bar Code) Supplier Labeling Standard Primary Data Message
* `N4` - National Drug Code in 5-4-2 Format
* `ON` - Customer Order Number
* `UK` - GTIN 14-digit Data Structure
* `UP` - UCC - 12
## Individual Relationship Codes
Used in the following APIs and properties:
* Professional claims `claimInformation.otherSubscriberInformation.individualRelationshipCode` property.
* Institutional claims `claimInformation.otherSubscriberInformation.individualRelationshipCode` property.
* Dental claims `claimInformation.otherSubscriberInformation.individualRelationshipCode` property.
You can use the following codes:
* `01` - Spouse
* `18` - Self
* `19` - Child
* `20` - Employee
* `21` - Unknown
* `39` - Organ Donor
* `40` - Cadaver Donor
* `53` - Life Partner
* `G8` - Other Relationship
## Insurance Type Codes
Used in the following APIs and properties:
* Professional claims `subscriber.insuranceTypeCode` and `claimInformation.otherSubscriberInformation.insuranceTypeCode` properties.
* Dental claims `subscriber.insuranceTypeCode` and `claimInformation.otherSubscriberInformation.insuranceTypeCode` properties.
You can use the following codes:
* `12` - Medicare Secondary Working Aged Beneficiary or Spouse with Employer Group Health Plan
* `13` - Medicare Secondary End-Stage Renal Disease Beneficiary in the Mandated Coordination Period with an Employer's Group Health Plan
* `14` - Medicare Secondary, No-fault Insurance including Auto is Primary
* `15` - Medicare Secondary Worker's Compensation
* `16` - Medicare Secondary Public Health Service (PHS)or Other Federal Agency
* `41` - Medicare Secondary Black Lung
* `42` - Medicare Secondary Veteran's Administration
* `43` - Medicare Secondary Disabled Beneficiary Under Age 65 with Large Group Health Plan (LGHP)
* `47` - Medicare Secondary, Other Liability Insurance is Primary
## Payment Responsibility Sequence Number Codes
Used in the following APIs and properties:
* Professional claims `subscriber.paymentResponsibilityLevelCode` and `claimInformation.otherSubscriberInformation.paymentResponsibilityLevelCode` properties.
* Institutional claims `claimInformation.otherSubscriberInformation.paymentResponsibilityLevelCode` property.
* Dental claims `subscriber.paymentResponsibilityLevelCode` and `claimInformation.otherSubscriberInformation.paymentResponsibilityLevelCode` properties.
You can use the following codes:
* `A` - Payer Responsibility Four
* `B` - Payer Responsibility Five
* `C` - Payer Responsibility Six
* `D` - Payer Responsibility Seven
* `E` - Payer Responsibility Eight
* `F` - Payer Responsibility Nine
* `G` - Payer Responsibility Ten
* `H` - Payer Responsibility Eleven
* `P` - Primary
* `S` - Secondary
* `T` - Tertiary
* `U` - Unknown; This code may only be used in payer to payer COB claims when the original payer determined the presence of this coverage from eligibility files received from this payer or when the original claim did not provide the responsibility sequence for this payer.
## Pricing/Repricing (Professional and Dental Claims)
Used in the professional claims and dental claims APIs.
### Exception Codes
Used in the following APIs and properties:
* Professional claims `claimInformation.claimPricingRepricingInformation.exceptionCode` and `claimInformation.serviceLines.linePricingRepricingInformation.exceptionCode` properties.
* Dental claims `claimInformation.claimPricingRepricingInformation.exceptionCode` and `claimInformation.serviceLines.linePricingRepricingInformation.exceptionCode` properties.
You can use the following codes:
* `1` - Non-Network Professional Provider in Network Hospital
* `2` - Emergency Care
* `3` - Services or Specialist not in Network
* `4` - Out-of-Service Area
* `5` - State Mandates
* `6` - Other
### Policy Compliance Codes
Used in the following APIs and properties:
* Professional claims `claimInformation.claimPricingRepricingInformation.policyComplianceCode` and `claimInformation.serviceLines.linePricingRepricingInformation.policyComplianceCode` properties.
* Dental claims `claimInformation.claimPricingRepricingInformation.policyComplianceCode` and `claimInformation.serviceLines.linePricingRepricingInformation.policyComplianceCode` properties.
You can use the following codes:
* `1` - Procedure Followed (Compliance)
* `2` - Not Followed - Call Not Made (Non-Compliance Call Not Made)
* `3` - Not Medically Necessary (Non-Compliance Non-Medically Necessary)
* `4` - Not Followed Other (Non-Compliance Other)
* `5` - Emergency Admit to Non-Network Hospital
### Pricing Methodology Codes
Used in the following APIs and properties:
* Professional claims `claimInformation.claimPricingRepricingInformation.pricingMethodologyCode` and `claimInformation.serviceLines.linePricingRepricingInformation.pricingMethodologyCode` properties.
* Dental claims `claimInformation.claimPricingRepricingInformation.pricingMethodologyCode` and `claimInformation.serviceLines.linePricingRepricingInformation.pricingMethodologyCode` properties.
You can use the following codes:
* `00` - Zero Pricing (Not Covered Under Contract)
* `01` - Priced as Billed at 100%
* `02` - Priced at the Standard Fee Schedule
* `03` - Priced at a Contractual Percentage
* `04` - Bundled Pricing
* `05` - Peer Review Pricing
* `07` - Flat Rate Pricing
* `08` - Combination Pricing
* `09` - Maternity Pricing
* `10` - Other Pricing
* `11` - Lower of Cost
* `12` - Ratio of Cost
* `13` - Cost Reimbursed
* `14` - Adjustment Pricing
### Reject Reason Codes
Used in the following APIs and properties:
* Professional claims `claimInformation.claimPricingRepricingInformation.rejectReasonCode` and `claimInformation.serviceLines.linePricingRepricingInformation.rejectReasonCode` properties.
* Dental claims `claimInformation.claimPricingRepricingInformation.rejectReasonCode` and `claimInformation.serviceLines.linePricingRepricingInformation.rejectReasonCode` properties.
You can use the following codes:
* `T1` - Cannot Identify Provider as TPO (Third Party Organization) Participant
* `T2` - Cannot Identify Payer as TPO (Third Party Organization) Participant
* `T3` - Cannot Identify Insured as TPO (Third Party Organization) Participant
* `T4` - Payer Name or Identifier Missing
* `T5` - Certification Information Missing
* `T6` - Claim does not contain enough information for re-pricing
## Service Authorization Exception Codes
Used in the following APIs and properties:
* Professional claims `claimInformation.claimSupplementalInformation.serviceAuthorizationExceptionCode` property
* Institutional claims `claimInformation.claimSupplementalInformation.serviceAuthorizationExceptionCode` property.
* Dental claims `claimInformation.claimSupplementalInformation.serviceAuthorizationExceptionCode` property
You can use the following codes:
* `1` - Immediate/Urgent Care
* `2` - Services Rendered in a Retroactive Period
* `3` - Emergency Care
* `4` - Client has Temporary Medicaid
* `5` - Request from County for Second Opinion to Determine if Recipient Can Work
* `6` - Request for Override Pending
* `7` - Special Handling
## Vision Condition Codes
Used in the professional claims `claimInformation.patientConditionInformationVision.conditionCodes` property.
* `L1` - General Standard of 20 Degree or .5 Diopter Sphere or Cylinder Change Met
* `L2` - Replacement Due to Loss or Theft
* `L3` - Replacement Due to Breakage or Damage
* `L4` - Replacement Due to Patient Preference
* `L5` - Replacement Due to Medical Reason
# CMS-1500 Claim Form PDF
Source: https://www.stedi.com/docs/healthcare/cms-1500-claim-form-pdf
***
title: CMS-1500 Claim Form PDF
sidebarTitle: 'CMS-1500 PDF'
----------------------------
Stedi automatically generates a [CMS-1500 Claim Form](https://www.nucc.org/index.php/1500-claim-form-mainmenu-35) PDF for each professional claim you submit.
We strongly recommend reviewing the following behavior and recommendations if you plan to send these PDFs to payers or retain them for your records.
## Retrieve PDFs
You can manually download generated any claim's generated CMS-1500 PDF from the transaction details page for the claim in Stedi.
You can also retrieve PDFs through either of the following endpoints:
* [CMS-1500 PDF: Business Identifier](/api-reference/healthcare/get-pdf-1500-business-identifier): Retrieve PDFs through a claim's business identifier. You can find the business identifier value in the `claimReference.correlationId` property Stedi returns in the synchronous claim submission response.
* [CMS-1500 PDF: Transaction ID
](/api-reference/healthcare/get-pdf-1500): Retrieve PDFs through the `transactionId` Stedi assigns to the processed claim. This ID is included in the transaction processed event for the claim, which you can receive automatically through [webhooks](/healthcare/configure-webhooks). You can also retrieve this ID from the transaction's details page in Stedi.
Both endpoints return a base64 encoded string of the PDF. To render the PDF, you must decode the base64 string and save it to a file with a `.pdf` extension.
## Generation notes
Note the following behavior and recommendations to generate optimal CMS-1500 PDFs.
### PDF background
You can generate CMS-1500 PDFs with a white background by adding the query parameter `?background=false` when calling the PDF generation endpoints.
The National Uniform Claim Committee (NUCC) and CMS provide exact specifications for blank CMS-1500 forms, including paper size and ink color. Many provider offices are accustomed to using these pre-printed forms, and their Practice Management System (PMS) applications are designed to print claim data onto them. Generating PDFs with a white background allows you to print the claim data directly onto official pre-printed forms.
### The PDF may truncate claim data.
The maximum length for many fields in the CMS-1500 Claim Form is less than the maximum length for the corresponding properties in the claim request.
**Recommendation:** Ensure that your claim data is within the maximum length for claim form fields. We especially recommend using [USPS abbreviations](https://pe.usps.com/text/pub28/28apc_002.htm) to avoid truncated addresses in the generated PDF.
### The PDF may omit the second line of some addresses.
Some CMS-1500 Claim Form items contain address fields that can only be mapped to a single address line. If you include the `address2` JSON property (X12 EDI `N302`) in your claim submission, that information may not appear in the PDF.
**Recommendation:** Put all street address line data into the `address1` JSON property (X12 EDI `N301`), ensuring that you adhere to the claim form length constraints.
### The PDF won't populate Item 7 when the patient is a dependent.
Stedi validates the claim data you submit to the API and uses it to generate a compliant X12 EDI transaction to send to the payer. The PDF is generated from the final X12 EDI transaction.
The X12 EDI standard specifies that claims should only contain the insured's address when the patient is the subscriber. To maintain compliance, Stedi doesn't include the insured's address information in the generated X12 EDI transaction when the patient is a dependent, even if you provided the subscriber's address in the original API request. Since this address information isn't present in final X12 EDI claim, it's also not added to Item 7 (Insured's Address) in the generated PDF.
### Payer address (Carrier Block)
You can populate the payer's address on the PDF by providing the `payerAddress` object in your claim submission API request. Include the payer's address details that you want to appear on the form.
### Standard form size
The generated PDFs use the standard 8.5" x 11" format.
## Edit PDFs
Single-page PDFs are editable so you can make any necessary adjustments before printing and sending them to payers. You can use any PDF editor to make changes to the generated CMS-1500 PDF.
## Print PDFs
Note the following behavior and recommendations when printing CMS-1500 PDFs.
* We recommend generating PDFs with a [white background](#pdf-background) if you plan to print them on pre-printed claim forms.
* The form boxes and labels **must** be printed in red ink and the item values **must** be printed in black ink for the claim form to be read by a scanner. Your vendor may choose not to process claim forms that don't conform to these specifications.
* Set the **Page Size & Handling** option to **Actual size** or the equivalent in your PDF reader application. The **Fit** option may cause the contents to be scaled down to fit within the printable area, causing the form fields to be misaligned when printed.
* Don't print forms from the Apple Preview app built in to macOS. There appear to be problems with field alignment and fonts. Instead, we recommend using either Adobe Acrobat or Google Chrome.
### Printer models
We generally recommend using business laser printers to print CMS-1500 PDFs. However, due to mechanical variations between printer models, we can't guarantee that the generated PDFs will align perfectly with pre-printed forms. You should always test the alignment with your printer before using the generated PDFs for official submissions.
You may not get acceptable results when using inkjet printer models because the file contents can extend beyond the normal printable area. If you do plan to use an inkjet printer, don't enable a **borderless** option because this may cause the printer (or printer driver) to slightly magnify the page image regardless of other print settings. This behavior can crop form edges and cause form fields to appear in the wrong positions. Some inkjet printers have a manual setting to change the extension amount, but this isn't always available and may not give consistent results.
# Interpret COB response
Source: https://www.stedi.com/docs/healthcare/cob-response
***
title: Interpret COB response
sidebarTitle: 'Interpret COB response'
--------------------------------------
The coordination of benefits (COB) response includes information about the patient's active health plans, subscriber information, and coordination of benefits.
Unlike standard eligibility checks, the COB response shape is standardized across all supported payers. There are no payer-specific variations in what information is included or how the response is structured.
## COB status
The `coordinationOfBenefits` object contains status information about whether a COB instance exists and whether Stedi was able to determine the primary payer.
{/* schema:COB:unwrap */}
```json
"coordinationOfBenefits": {
"classification": "CobInstanceExistsPrimacyDetermined",
"instanceExists": true,
"primacyDetermined": true,
"coverageOverlap": true,
"benefitOverlap": true
}
```
A COB check response can have one of the following statuses, indicated by the `coordinationOfBenefits.classification` property.
| status | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MemberFoundNoCob` | The patient has coverage with the payer you checked, but Stedi didn't find any other health plans with overlapping coverage. Note that Stedi can only report information for other COB-supported health plans from our payer list. For example, if the individual has coverage from Cigna and Medicare, a COB check to Cigna will state that no COB was detected, since Medicare is not a supported payer. You can find a complete list of supported payers for COB checks in the [Payer Network](https://www.stedi.com/healthcare/network?query=eyIyNzAiOnt9LCIyNzYiOnt9LCI4MzUiOnt9LCI4MzdQIjp7fSwiODM3SSI6e30sIjgzN0QiOnt9LCJDT0IiOnsiaXNTdXBwb3J0ZWQiOnRydWV9fQ%3D%3D\&page=0). |
| `CoverageOverlapNoBenefitOverlap` | The patient has overlapping coverage with at least one other health plan, but there is no benefit overlap between the plans. Coordination of benefits is not required. |
| `CoverageOverlapExistsNotSubjectToCob` | The patient has overlapping coverage with at least one other health plan, but coordination of benefits is not required. |
| `CobInstanceExistsPrimacyUndetermined` | The patient has overlapping coverage with at least one other health plan and coordination of benefits is required. However, Stedi could not determine the primary payer. We recommend contacting the patient's health plans for further guidance. |
| `CobInstanceExistsPrimacyDetermined` | The patient has overlapping coverage with at least one other health plan, and Stedi was able to identify the primary payer. |
## Payer primacy
The response includes a `benefitsInformation` object with `code` = `R` when Stedi finds overlapping coverage with another health plan.
The `benefitsInformation.benefitsRelatedEntities` object contains information about the other payer, and the `entityIdentifier` property indicates the payer's primacy for payment on claims when this information is available. It can be set to:
* `Payer`: Stedi didn't find a COB instance or could not determine primacy.
* `Primary Payer`: This payer is the primary payer for the service type.
* `Secondary Payer`: This payer is the secondary payer for the service type.
* `Tertiary Payer`: This payer is the tertiary payer for the service type.
In the following example, the patient has overlapping coverage for medical care services with Cigna, the primary payer for medical care services.
{/* schema:COBBenefitsInformation */}
```json
{
"code": "R",
"name": "Other or Additional Payor",
"serviceTypeCodes": [
"1"
],
"serviceTypes": [
"Medical Care"
],
"benefitsDateInformation": {
"coordinationOfBenefits": "2024-07-01"
},
"benefitsRelatedEntities": [
{
"entityIdentifier": "Primary Payer",
"entityName": "CIGNA",
"entityIdentification": "PI",
"entityIdentificationValue": "1006"
},
{
"entityIdentifier": "Insured or Subscriber",
"entityFirstname": "JOHN",
"entityMiddlename": "X",
"entityIdentification": "MI",
"entityIdentificationValue": "00000000000",
"entityLastname": "DOE"
}
],
"subscriber": {
"dateOfBirth": "2002-12-31"
}
}
```
When Stedi can't reliably determine primacy, you should contact the patient's health plans directly for further guidance.
### Primacy rules
Medicare and Medicare Advantage plans are not supported, so these plans aren't included in the primacy determination process.
Our COB service follows the guidelines set by the [National Association of Insurance Commissioners (NAIC)](https://content.naic.org/) to determine payer primacy. You may also want to refer to these guidelines when submitting claims.
#### Plan responsibilities
In almost all cases, the **primary** plan pays benefits first as if no other plan exists. The one exception to this policy is when the patient has both an HMO (closed network plan) and a PPO (open network plan). When the HMO is the primary plan and the PPO is secondary, the PPO will pay first when the patient uses out-of-network providers unless it's an emergency or an authorized referral covered by the HMO.
When multiple policies are treated as a single plan, the primacy determination applies to the entire plan. The plans must coordinate amongst themselves according to their contracts. If more than one insurance company provides benefits under the plan, the one designated as primary is responsible for complying with coordination of benefits rules.
#### Order of benefits rules
After the primary plan pays, each subsequent plan pays remaining eligible costs. Each health plan determines their order of benefits using the first of the following rules that apply:
**1. Non-Dependent vs. Dependent vs. Medicare**
* A plan covering the patient as an employee, subscriber, or retiree is primary over a plan that covers them as a dependent.
* If the patient also has Medicare, special rules apply:
* Medicare is secondary to a plan covering the person as a dependent.
* Medicare is primary to a plan covering the person as an employee (from an employer with more than 20 employees), subscriber, or retiree.
* If the patient has all three plan types, the order of primacy is: Medicare, then the plan covering the person as a dependent, and then any other plans.
**2. Dependent child with multiple plans**
Note that the following rules are the same regardless of whether the subscribers of the multiple plans are the child's parents or other significant individuals in their life (not their parents).
* If the two subscribers are married or living together: The subscriber with the birthday that occurs first in the calendar year has the primary plan. If both subscribers have the same birthday, the plan that has covered the child the longest is primary.
* If the dependent child's coverage under the spouse's plan began on the same date as their coverage under either or both parents' plans, the order of benefits will be determined using the birthday rule.
* If the two subscribers are divorced, separated, or not living together, a court order typically decides which plan is primary. Otherwise:
* The plan of the custodial parent is primary.
* The plan of the spouse of the custodial parent is secondary.
* The plan of the non-custodial parent is tertiary.
* The plan of the spouse of the non-custodial parent is last.
* If a dependent child has coverage under either or both parents' plans and is also covered as a dependent under a spouse's plan, apply rule 5 - Length of coverage.
**3. Active vs. retired employees**
Coverage from a current employer (active employee) is primary to retired or laid-off employee plans.
**4. COBRA vs. state continuation coverage**
Employer-based plans are primary to COBRA coverage.
**5. Length of coverage**
If other rules don’t decide, the plan covering the person for the longest time is primary.
**6. Final rule (If no other rules apply)**
If no clear primary plan is determined, costs are split equally between the plans.
# Sample response interpretation
The following example COB response shows information for a dependent who is covered by multiple health plans through their parents' policies. The COB check was submitted to Aetna with a service type code of `30` and a date of service of `2024-11-27`.
The response indicates the following:
* **Active coverage:** The patient has active coverage with Aetna for medical care services, pharmacy services, and vision services. This is indicated by the three objects in the `benefitsInformation` array with the `code` set to `1`.
* **Coverage overlap:** The patient has overlapping coverage for medical care services between two health plans. This is indicated by the `benefitsInformation` object with the `code` set to `R`.
* **Primacy:** The other health plan is Cigna, listed in `benefitsInformation.benefitsRelatedEntities`. Cigna is the primary payer for medical care services. Note that the ID returned in this property is proprietary to our COB check product, so you can't use it as the Payer ID for eligibility checks or other API requests to Stedi. It likely doesn't match the Payer IDs listed in the [Payer Network](https://www.stedi.com/healthcare/network).
* **COB instance:** There is a COB instance for medical care services on the date of service provided in the request. This is indicated in the `coordinationOfBenefits` object.
Based on this response, you must send claims first to Cigna as the primary payer for medical care services. Once Cigna adjudicates the claim, you can send another one, if necessary, to Aetna as the secondary payer (subject to specific payer claims processing rules).
Before sending claims we'd also recommend sending a separate eligibility check to Aetna to verify coverage status.
{/* schema:CoordinationOfBenefitsResponseContent */}
```json
{
"benefitsInformation": [
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"1"
],
"serviceTypes": [
"Medical Care"
],
"benefitsDateInformation": {
"benefitBegin": "2023-03-01"
},
"subscriber": {
"dateOfBirth": "2002-02-27"
}
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"88"
],
"serviceTypes": [
"Pharmacy"
],
"benefitsDateInformation": {
"benefitBegin": "2023-03-01"
},
"subscriber": {
"dateOfBirth": "2002-02-27"
}
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"AL"
],
"serviceTypes": [
"Vision (Optometry)"
],
"benefitsDateInformation": {
"benefitBegin": "2023-03-01"
},
"subscriber": {
"dateOfBirth": "2002-02-27"
}
},
{
"code": "R",
"name": "Other or Additional Payor",
"serviceTypeCodes": [
"1"
],
"serviceTypes": [
"Medical Care"
],
"benefitsDateInformation": {
"coordinationOfBenefits": "2024-07-01"
},
"benefitsRelatedEntities": [
{
"entityIdentifier": "Primary Payer",
"entityName": "CIGNA",
"entityIdentification": "PI",
"entityIdentificationValue": "1006"
},
{
"entityIdentifier": "Insured or Subscriber",
"entityFirstname": "JOHN",
"entityMiddlename": "X",
"entityIdentification": "MI",
"entityIdentificationValue": "00000000000",
"entityLastname": "DOE"
}
],
"subscriber": {
"dateOfBirth": "2002-12-31"
}
}
],
"coordinationOfBenefits": {
"classification": "CobInstanceExistsPrimacyDetermined",
"instanceExists": true,
"primacyDetermined": true,
"coverageOverlap": true,
"benefitOverlap": true
},
"dependent": {
"firstName": "JORDAN",
"lastName": "DOE",
"gender": "M",
"dateOfBirth": "2002-12-31",
"relationToSubscriber": "Child",
"relationToSubscriberCode": "19",
"address": {
"address1": "1 MAIN ST.",
"city": "NEW YORK",
"state": "NY",
"postalCode": "10000"
}
},
"errors": [],
"meta": {
"applicationMode": "production",
"traceId": "01JDQFT4W3KTWZNTADEZ55BFFX",
"outboundTraceId": "01JDQFT4W3KTWZNTADEZ55BFFX"
},
"payer": {
"name": "Aetna",
"payerIdentification": "AETNA-USH"
},
"provider": {
"providerOrgName": "AETNA-USH",
"npi": "1999999984"
},
"subscriber": {
"memberId": "W000000000",
"firstName": "JOHN",
"lastName": "DOE",
"address": {
"address1": "1 MAIN ST.",
"city": "NEW YORK",
"state": "NY",
"postalCode": "10000"
}
}
}
```
## Request and response examples
The following examples show request and response data for common COB scenarios.
### COB exists, primacy determined
In the following example, the COB check was submitted to Cigna with a service type code of `30` and a date of service of `2024-12-19`.
The response indicates that the patient has active coverage with Cigna for medical care services, and that there is overlapping coverage with Kaiser Foundation Health Plan of Massachusetts. COB is required for medical care services, and Kaiser is the primary payer.
{/* schema:CoordinationOfBenefitsRequestContent */}
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/coordination-of-benefits \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"test": false,
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "PPROVIDER",
"npi": "1999999984"
},
"subscriber": {
"memberId": "X999999999",
"firstName": "Goofy",
"lastName": "Goof",
"dateOfBirth": "1948-11-01"
},
"encounter": {
"dateOfService": "2024-12-19",
"serviceTypeCode": "30"
}
}'
```
{/* schema:CoordinationOfBenefitsResponseContent */}
```json
{
"benefitsInformation": [
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["1"],
"serviceTypes": ["Medical Care"],
"benefitsDateInformation": {
"benefitBegin": "2024-01-01"
},
"subscriber": {
"dateOfBirth": "1948-11-01"
}
},
{
"code": "R",
"name": "Other or Additional Payor",
"serviceTypeCodes": ["1"],
"serviceTypes": ["Medical Care"],
"benefitsDateInformation": {
"coordinationOfBenefits": "2024-01-01"
},
"benefitsRelatedEntities": [
{
"entityIdentifier": "Primary Payer",
"entityName": "KAISER FOUNDATION HEALTH PLAN OF MAS",
"entityIdentification": "PI",
"entityIdentificationValue": "1009"
},
{
"entityIdentifier": "Insured or Subscriber",
"entityFirstname": "GOOFY",
"entityMiddlename": "X",
"entityIdentification": "MI",
"entityIdentificationValue": "999999999",
"entityLastname": "GOOF"
}
],
"subscriber": {
"dateOfBirth": "1948-11-01"
}
}
],
"coordinationOfBenefits": {
"classification": "CobInstanceExistsPrimacyDetermined",
"instanceExists": true,
"primacyDetermined": true,
"coverageOverlap": true,
"benefitOverlap": true
},
"dependent": {
"firstName": "GOOFY",
"lastName": "GOOF",
"gender": "M",
"dateOfBirth": "1948-11-01",
"relationToSubscriber": "Spouse",
"relationToSubscriberCode": "01",
"address": {
"address1": "3 DISNEY RD",
"city": "ORLANDO",
"state": "FL",
"postalCode": "32801"
}
},
"errors": [],
"meta": {
"applicationMode": "production",
"traceId": "01JJQRFYSXPKNYQ96EVM7XDXC4",
"outboundTraceId": "01JJQRFYSXPKNYQ96EVM7XDXC4"
},
"payer": {
"name": "CIGNA",
"payerIdentification": "CIGNA-HCIN"
},
"provider": {
"providerOrgName": "PROVIDER",
"npi": "1999999984"
},
"subscriber": {
"memberId": "X99999999",
"firstName": "MRS",
"lastName": "GOOF",
"groupNumber": "12345678",
"address": {
"address1": "3 DISNEY RD",
"city": "ORLANDO",
"state": "FL",
"postalCode": "32801"
}
}
}
```
### Coverage overlap, no benefit overlap
In the following example, the COB check was submitted to Cigna with a service type code of `30` and a date of service of `2025-01-01`.
The response indicates that the patient has active coverage with Cigna for medical care services, and that there is overlapping coverage with Aetna for dental care services. There is no benefit overlap between the two health plans because dental and medical benefits have two different service type codes. COB is not required.
{/* schema:CoordinationOfBenefitsRequestContent */}
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/coordination-of-benefits \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"test": false,
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "PROVIDER",
"npi": "1999999984"
},
"subscriber": {
"memberId": "X999999999",
"firstName": "MICKEY",
"lastName": "MOUSE",
"dateOfBirth": "1928-11-28"
},
"encounter": {
"dateOfService": "2025-01-01",
"serviceTypeCode": "30"
}
}'
```
```json
{
"benefitsInformation": [
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["1"],
"serviceTypes": ["Medical Care"],
"benefitsDateInformation": {
"benefitBegin": "2024-10-03"
},
"subscriber": {
"dateOfBirth": "1925-11-28"
},
"dependent": {
"firstName": "MICKEY",
"lastName": "MOUSE",
"memberId": "X999999999",
"dateOfBirth": "1928-11-28",
"familySeqNum": "0003",
"relationToSubscriber": "Spouse",
"relationToSubscriberCode": "01"
}
},
{
"code": "R",
"name": "Other or Additional Payor",
"serviceTypeCodes": ["35"],
"serviceTypes": ["Dental Care"],
"benefitsDateInformation": {
"periodStart": "2024-10-03"
},
"benefitsRelatedEntities": [
{
"entityIdentifier": "Payer",
"entityName": "AETNA",
"entityIdentification": "PI",
"entityIdentificationValue": "1000"
},
{
"entityIdentifier": "Insured or Subscriber",
"entityFirstname": "MINNIE",
"entityMiddlename": "X",
"entityIdentification": "MI",
"entityIdentificationValue": "X999999999",
"entityLastname": "MOUSE"
}
],
"subscriber": {
"dateOfBirth": "1925-11-28"
},
"dependent": {
"firstName": "MICKEY",
"lastName": "MOUSE",
"memberId": "X999999999",
"dateOfBirth": "1928-11-28",
"familySeqNum": "0003",
"relationToSubscriber": "Spouse",
"relationToSubscriberCode": "01"
}
}
],
"coordinationOfBenefits": {
"classification": "CoverageOverlapNoBenefitOverlap",
"instanceExists": true,
"coverageOverlap": true,
"benefitOverlap": false,
"primacyDetermined": false
},
"dependent": {
"firstName": "MICKEY",
"lastName": "MOUSE",
"gender": "M",
"dateOfBirth": "1928-11-28",
"relationToSubscriber": "Spouse",
"relationToSubscriberCode": "01",
"address": {
"address1": "3 DISNEY RD",
"city": "ORLANDO",
"state": "FL",
"postalCode": "32801"
}
},
"errors": [],
"meta": {
"applicationMode": "production",
"traceId": "01JJVW6QJWXESXYAAAE4H996HR",
"outboundTraceId": "01JJVW6QJWXESXYAAAE4H996HR"
},
"payer": {
"name": "CIGNA",
"payerIdentification": "CIGNA-HCIN"
},
"provider": {
"providerOrgName": "PROVIDER",
"npi": "1999999984"
},
"subscriber": {
"memberId": "X99999999",
"firstName": "MINNIE",
"lastName": "MOUSE",
"middleName": "X",
"groupNumber": "3340181",
"address": {
"address1": "3 DISNEY RD",
"city": "ORLANDO",
"state": "FL",
"postalCode": "32801"
}
}
}
```
### Member found, no COB
In the following example, the COB check was submitted to UnitedHealthcare with a service type code of `30` and a date of service of `2023-01-10`.
The response indicates that the patient has active coverage with UnitedHealthcare for medical care services, but there is no overlapping coverage with any other health plan.
{/* schema:CoordinationOfBenefitsRequestContent */}
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/coordination-of-benefits \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"test": false,
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "PROVIDER",
"npi": "1999999984"
},
"subscriber": {
"memberId": "999999999",
"firstName": "Donald",
"lastName": "Duck",
"dateOfBirth": "1960-01-01"
},
"dependent": {
"firstName": "Huey",
"lastName": "Duck",
"dateOfBirth": "1990-01-01"
},
"encounter": {
"dateOfService": "2023-01-10",
"serviceTypeCode": "30"
}
}'
```
{/* schema:CoordinationOfBenefitsResponseContent */}
```json
{
"benefitsInformation": [
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["1"],
"serviceTypes": ["Medical Care"],
"benefitsDateInformation": {
"benefitBegin": "2024-01-01"
}
}
],
"coordinationOfBenefits": {
"classification": "MemberFoundNoCob",
"instanceExists": false,
"coverageOverlap": false,
"benefitOverlap": false,
"primacyDetermined": false
},
"dependent": {
"firstName": "HUEY",
"lastName": "DUCK",
"middleName": "M",
"gender": "F",
"dateOfBirth": "1990-01-01",
"relationToSubscriber": "Child",
"relationToSubscriberCode": "19",
"address": {
"address1": "25 THE ROAD",
"city": "READING",
"state": "MA",
"postalCode": "01867"
}
},
"errors": [],
"meta": {
"applicationMode": "production",
"traceId": "09JJSWD8RBGZMVCCYGQZS3P1F7",
"outboundTraceId": "09JJSWD8RBGZMVCCYGQZS3P1F7"
},
"payer": {
"name": "UnitedHealthcare",
"payerIdentification": "UHC"
},
"provider": {
"providerOrgName": "PROVIDER",
"npi": "1999999984"
},
"subscriber": {
"memberId": "999999999",
"firstName": "DONALD",
"lastName": "DUCK",
"middleName": "X",
"address": {
"address1": "25 THE ROAD",
"city": "READING",
"state": "MA",
"postalCode": "01867"
}
}
}
```
## Follow up with eligibility checks
Our COB data is updated weekly, and the response doesn't contain complete details about the patient's coverage with each health plan.
When Stedi finds overlapping coverage, we strongly recommend conducting follow-up [eligibility checks](/healthcare/send-eligibility-checks) with each payer to verify coverage status and retrieve the patient's complete, up-to-date benefits information.
# COB troubleshooting
Source: https://www.stedi.com/docs/healthcare/cob-troubleshooting
***
title: COB troubleshooting
sidebarTitle: 'Troubleshooting'
-------------------------------
A list of potential errors and possible resolutions when submitting coordination of benefits (COB) checks.
## Inaccurate patient data
COB checks are significantly more sensitive to data accuracy than eligibility checks. To perform successful COB checks, the patient information you provide in the check **must** match the payer's data exactly.
For example, if a payer has a patient's name stored as "Jonathan Doe", they may return benefits information when you submit an eligibility check for "Jon Doe", as long as they can identify the patient through the other information provided. However, a COB request for "Jon Doe" will fail because the name doesn't match the payer's records exactly.
To avoid unnecessary COB check failures, we strongly recommend that you first submit an eligibility check request for the patient. Then use the following data from the successful eligibility response to build the COB request: `firstName`, `lastName`, `dateOfBirth`, `memberId`.
## Invalid or unsupported payer ID
COB requests require a valid payer ID in the `tradingPartnerServiceId` property. Visit the Stedi [Payer Network](https://www.stedi.com/healthcare/network?query=eyIyNzAiOnt9LCIyNzYiOnt9LCI4MzUiOnt9LCI4MzdQIjp7fSwiODM3SSI6e30sIjgzN0QiOnt9LCJDT0IiOnsiaXNTdXBwb3J0ZWQiOnRydWV9fQ%3D%3D\&page=0) for a complete list of supported payers and their payer IDs.
You should also ensure that you're sending the request to the correct payer entity. For example, Blue Cross Blue Shield (BCBS) has multiple entities that operate in different states. If you send a request to the wrong entity, the request will fail with an `AAA` = `75` error (Subscriber/Insured Not Found).
## Missing data
COB requests must contain the patient’s `firstName`, `lastName`, `dateOfBirth`, plus `memberId` and/or `ssn`. If you do not send all data points, Stedi returns an HTTP `400` error with a message listing the missing data.
{/* schema:ValidationExceptionResponseContent */}
```json
{
"fieldList": [
{
"path": "/subscriber/dateOfBirth",
"message": "Value at '/subscriber/dateOfBirth' failed to satisfy constraint: Member must not be null"
}
],
"message": "1 validation error detected. Value at '/subscriber/dateOfBirth' failed to satisfy constraint: Member must not be null"
}
```
## Request found multiple patients
The `Duplicate Subscriber/Insured ID Number` error can occur when Stedi finds more than one member ID for the patient in the request. For example, this could occur if you only provide the patient's Social Security Number (SSN), and the search returns more than one member ID associated with that SSN.
In this case, Stedi returns a HTTP `200` response with an `AAA` error in the `subscriber` object.
{/* schema:COBResponseSubscriber:unwrap */}
```json
"subscriber": {
"memberId": "123456789",
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1961-10-21",
"aaaErrors": [
{
"field": "AAA",
"code": "76",
"description": "Duplicate Subscriber/Insured ID Number",
"followupAction": "Please Correct and Resubmit",
"location": "Loop 2100C",
"possibleResolutions": "Duplicate member ID was found in the payer database."
}
]
}
```
## Member not found
If Stedi cannot find a member ID for the patient in the request, it returns an HTTP `200` response with an `AAA` error in the `subscriber` object.
{/* schema:COBResponseSubscriber:unwrap */}
```json
"subscriber": {
"memberId": "123456789",
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1961-10-21",
"aaaErrors": [
{
"field": "AAA",
"code": "75",
"description": "Subscriber/Insured Not Found",
"followupAction": "Please Correct and Resubmit",
"location": "Loop 2100C",
"possibleResolutions": "- Subscriber was not found."
}
]
}
```
Mismatches in the `memberId` are one of the most common causes of `Subscriber/Insured Not Found` errors. We strongly recommend first performing an eligibility check and using the `memberId` in the response to populate your COB check.
You will also receive a `Subscriber/Insured Not Found` error if you try to submit a COB check to a Medicare or Medicare Advantage plan. These plans aren't supported for COB checks.
## Invalid service dates
The service dates you provide **must** be within the past 2 years. COB checks don't support requests with dates outside of this range.
Don't send service dates that are in the future. Future service dates typically result in errors from the payer.
## Inactive coverage
For COB checks to return a positive result, the patient must have active coverage. Sometimes, you can receive a false negative or error on a COB check when a patient's coverage has very recently changed. For example, if the patient recently became eligible for coverage within the last few days, that information may not yet be reflected in the COB member data, and you will receive a `Subscriber/Insured Not Found` error.
Payers typically update COB member data on a weekly basis. If you receive an error and the patient's coverage has recently changed, we recommend trying again next week to give the changes time to propagate to the COB database.
## AAA errors
The COB response may contain one or more `AAA` errors specify issues with your request and any recommended follow-up actions. Stedi includes this information in the `aaaErrors` object in the response JSON.
`AAA` errors can be present at multiple different levels in the response, depending on the type. In the COB response, the `subscriber`, `dependent`, and `provider` objects can each contain their own `aaaErrors` array.
Common causes for AAA errors include:
* Missing or incorrect information for the subscriber, dependent, provider, or payer. In this case, you should correct any errors before resubmitting.
* Issues with payer enrollment. Many of these issues require that the provider contact the payer directly to resolve, due to PHI/HIPAA guidelines.
Each error contains a code field that corresponds to a `followupAction`:
* `C` - Please correct and resubmit
* `N` - Resubmission not allowed
* `P` - Please resubmit original transaction
* `R` - Resubmission allowed
* `S` - Do not resubmit; Inquire initiated to a third party
* `Y` - Do not resubmit; We will hold your request and respond again shortly
# Configure webhooks
Source: https://www.stedi.com/docs/healthcare/configure-webhooks
***
title: 'Configure webhooks'
sidebarTitle: 'Configure webhooks'
----------------------------------
You can set up webhooks that automatically send claim processing events to your endpoint.
These events contain the information you need to retrieve 277CA claim acknowledgment and 835 Electronic Remittance Advice (ERA) responses through Stedi APIs. They can also help you monitor your claims pipeline when you're submitting claims through [Stedi SFTP](/healthcare/submit-claims-sftp-connection).
You can either create a single webhook that forwards events from all transactions, or create a separate webhook for each transaction type.
Configuring a webhook involves:
* Creating a [credential set](#credential-set) for authentication to the endpoint.
* Creating a [webhook](#webhook) that specifies the URL where Stedi should deliver events.
* Adding one or more [event bindings](#event-bindings) that trigger the webhook.
## Credential set
A credential set defines how to authenticate with a specific API. You can use a single credential set across multiple webhooks. Stedi supports the following types of configurations.
\| Type | Description |
\| ---------- | -------------------------------------------------------------------------------------------------------------------------- |
\| API Keys | The API keys as headers in the request. The most common version is ‘bearer tokens’. |
\| Basic Auth | [HTTP Basic Auth](https://developer.mozilla.org/en-US/Web/HTTP/Authentication), where you provide a username and password. |
\| None | For endpoints that don't require any authentication. |
### Unauthenticated endpoints
When using the 'None' credential set type in webhooks, it's functionally the same as using 'API Keys'. However, we set a dummy value for `Header name` and `Value` (`x-stedi-noauth` and `dummy`). Since the receiving API isn't authenticating the call, it will ignore these values and accept the request.
### Create credential set
You can define a credential set as part of configuring a new webhook. You can also create a new credential set independently and then attach it to one or more webhooks.
To create a credential set:
1. Go to the [Webhooks](https://portal.stedi.com/app/webhooks) page.
2. Click **Manage credentials**, and then click **Create credential set**.
3. Enter a name.
4. Choose the appropriate **Authentication type**.
5. Enter the details.
6. Click **Create credential set**.
## Webhook
A webhook defines which URL endpoint Stedi should call when the webhook is invoked, and which HTTP method to use (`POST`, `PUT`, `GET`, `PATCH`, `DELETE`).
You can only attach one credential set to each webhook. However, you might have multiple webhooks for a single system integration, each with a different endpoint.
### Create webhook
To create a new webhook:
1. Go to the [Webhooks](https://portal.stedi.com/app/webhooks) page.
2. Click **Create webhook**.
3. Enter a name.
4. Choose a **Method** and enter an **Endpoint** URL. This is where Stedi delivers the events when the webhook is invoked.
5. Select a **Credential set** to use for authentication or create a new one for this endpoint.
6. (Optional) Set the **Concurrency**. You can set the maximum number of deliveries that Stedi will attempt to deliver to the endpoint at one time. This can help you avoid overloading the target service.
## Event bindings
Event bindings allow you to specify which events trigger the webhook. You can create multiple event bindings for a single webhook. For example, you may want to create an event binding for each type of transaction you want to send to your API.
### Create event binding
To create a new event binding:
1. Go to the [Webhooks](https://portal.stedi.com/app/webhooks) page.
2. Click the webhook.
3. Click the **Event bindings** tab.
4. Click **New event binding**.
5. Choose **Transaction processed** as the **Event type**.
6. (Optional) Set one or more [filters](#event-filters).
7. Click **Create binding**.
### Choosing event types
The recommended event bindings depend on your use case:
* **API claim submission:** At a minimum, you should create an event binding for transaction processed events because they contain the information you need to retrieve claim responses from Stedi. You may also want to set up event bindings for file delivered and file failed events.
* **SFTP claim submission:** At a minimum, you should create an event binding for file failed events because they're emitted when Stedi is unable to deliver your claim to the payer. You may also want to set up event bindings for file delivered events and transaction processed events.
The file processed and fragment processed events are not relevant to claims
processing.
**Transaction processed events**
Stedi emits a transaction processed event after it successfully receives and translates a payer or intermediary clearinghouse response into JSON. It also emits this event once it successfully translates a JSON claim submission into X12 EDI format for the payer. The event payload contains the information you need to retrieve processed responses through Stedi APIs:
* `x12.transactionSetIdentifier` specifies the transaction type (277 or 835).
* `transactionId` allows you to retrieve the transaction in JSON format using either the [277CA Report](/api-reference/healthcare/get-healthcare-reports-277) or [835 ERA Report](/api-reference/healthcare/get-healthcare-reports-835) endpoint.
* `fileExecutionId` allows you to retrieve the transaction in X12 EDI format through the [Get Execution Input](/api-reference/edi-platform/core/get-executions-input) endpoint.
Even if you plan to retrieve claim responses through Stedi SFTP, you may want to monitor these events so you can receive alerts when new claim responses are available.
```json tab="processed 277CA"
{
"event": {
"version": "0",
"id": "f972fb53-653a-1747-ce30-bed15fc04f5c",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2024-07-18T16:21:24Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/transactions/f0d3f790-0bc9-432b-93kd-e4b7ece67946"
],
"detail": {
"transactionId": "f0d4f780-0ec9-432b-93gd-e4b7ece93946",
"direction": "INBOUND",
"mode": "test",
"fileExecutionId": "9f76b485-6hca-43bf-917e-d5b54bec6234",
"processedAt": "2024-07-18T16:21:24.658Z",
"fragments": null,
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"url": "https://core.us.stedi.com/2023-08-01/transactions/f0d9f790-0ec9-431b-93fd-e4h7ece63946/input",
"sizeBytes": 1313,
"model": "transaction"
},
{
"artifactType": "application/json",
"usage": "output",
"url": "https://core.us.stedi.com/2023-08-01/transactions/f0d3f740-0ec9-432b-98fd-e4b7ece63946/output",
"sizeBytes": 5602,
"model": "transaction"
}
],
"partnership": {
"partnershipId": "local-clearinghouse-test",
"partnershipType": "x12",
"sender": {
"profileId": "clearinghouse-test"
},
"receiver": {
"profileId": "local"
}
},
"x12": {
"transactionSetting": {
"guideId": "01J1M50C1Q44KYDZY8V7R1TPBW",
"transactionSettingId": "01J1M50P9623BFE0FFT5Q2BR49"
},
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "0",
"controlNumber": 11
},
"functionalGroup": {
"controlNumber": 11,
"release": "005010X214",
"date": "2024-07-18",
"time": "16:20:47",
"functionalIdentifierCode": "HN"
},
"transaction": {
"controlNumber": "1001",
"transactionSetIdentifier": "277"
},
"receiver": {
"applicationCode": "001690149382",
"isa": {
"qualifier": "ZZ",
"id": "001690149382"
}
},
"sender": {
"applicationCode": "STEDITEST",
"isa": {
"qualifier": "ZZ",
"id": "STEDITEST"
}
}
}
},
"connectionId": "01J1M5124B2HWMNN91Q3Z6AM61"
}
}
}
```
```json tab="processed 835 ERA"
{
"event": {
"version": "0",
"id": "5d1bcb90-cb0b-1844-5b93-86d5e5b9c4a8",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2025-07-14T20:43:39Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/transactions/95e7786c-7066-4494-b83a-b1f300624902"
],
"detail": {
"transactionId": "95e7786c-7066-4494-b83a-b1f300624902",
"direction": "INBOUND",
"mode": "test",
"fileExecutionId": "5d30f0a0-63af-4aeb-b96c-353b4b25c99a",
"processedAt": "2025-07-14T20:43:39.808Z",
"fragments": null,
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"url": "https://core.us.stedi.com/2023-08-01/transactions/95e7786c-7066-4494-b83a-b1f300624902/input",
"sizeBytes": 2016,
"model": "transaction"
},
{
"artifactType": "application/json",
"usage": "output",
"url": "https://core.us.stedi.com/2023-08-01/transactions/95e7786c-7066-4494-b83a-b1f300624902/output",
"sizeBytes": 13864,
"model": "transaction"
}
],
"partnership": {
"partnershipId": "local-clearinghouse-test",
"partnershipType": "x12",
"sender": {
"profileId": "clearinghouse-test"
},
"receiver": {
"profileId": "local"
}
},
"x12": {
"transactionSetting": {
"guideId": "01J8JH1SGTB2FYKN2PG4MH84RP",
"transactionSettingId": "01J8JH23VA3G2X8GENVVE6XZB9"
},
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "0",
"controlNumber": 1
},
"functionalGroup": {
"controlNumber": 1,
"release": "005010X221A1",
"date": "2025-07-14",
"time": "20:43:21",
"functionalIdentifierCode": "HP"
},
"transaction": {
"controlNumber": "0001",
"transactionSetIdentifier": "835"
},
"receiver": {
"applicationCode": "599264680681",
"isa": {
"qualifier": "ZZ",
"id": "599264680681"
}
},
"sender": {
"applicationCode": "STEDITEST",
"isa": {
"qualifier": "ZZ",
"id": "STEDITEST"
}
}
}
},
"connectionId": "01JE9257XJ4G4YFMXCHJPFR434"
}
}
}
```
**File delivered events**
Stedi emits a file delivered event when it successfully generates and delivers a claim. You may want to send these events to your system for monitoring and alerting.
Note that this event is emitted when Stedi delivers your claim to our connection with the payer. It doesn't indicate whether the payer received the claim or whether they have accepted or rejected it.
```json file.delivered.v2 event
{
"event": {
"version": "0",
"id": "3fb45b5f-bd7f-f9d0-c0a2-84946f20a9da",
"detail-type": "file.delivered.v2",
"source": "stedi.core",
"account": "",
"time": "2025-05-06T19:35:17Z",
"region": "us-east-1",
"resources": [],
"detail": {
"fileExecutionId": "e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9",
"processedAt": "2025-05-05T20:14:57.882927984Z",
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"sizeBytes": 1270,
"url": "https://core.us.stedi.com/2023-08-01/executions/e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9/input",
"model": "execution"
},
{
"artifactType": "application/edi-x12",
"usage": "output",
"sizeBytes": 1270,
"url": "https://core.us.stedi.com/2023-08-01/executions/e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9/output",
"model": "execution"
}
],
"connection": {
"connectionType": "STEDI_ACCOUNT_FTP",
"connectionId": "01JM0XF37DXZ3THZ7N75YJTW52"
},
"delivery": {
"status": "DELIVERED",
"message": "Delivered to 'Test Account SFTP'",
"artifactId": "9d7c38f4-410b-4032-aad4-016d8140b265.x12"
}
}
}
}
```
**File failed events**
Stedi emits a file failed event when it either fails to process a response from a payer or cannot deliver a submitted claim.
If you're submitting claims through Stedi's SFTP connection, we strongly recommend monitoring these events so that you can receive instant notifications when a submitted claim fails due to validation errors in the EDI file.
File failed events can indicate connection problems or other issues that our engineering team must resolve with the payer. If you're submitting claims through Stedi APIs, you may want to also monitor these events so you can alert our customer support team if needed.
```json file failed event
{
"event": {
"version": "0",
"id": "cef43062-0258-cbac-b06d-ec6a21f03c69",
"detail-type": "file.failed.v2",
"source": "stedi.core",
"account": "",
"time": "2025-06-05T11:26:16Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/executions/7590afcd-26d7-4182-a8fc-1d1051e2815c"
],
"detail": {
"fileExecutionId": "7590afcd-26d7-4182-a8fc-1d1051e2815c",
"direction": "INBOUND",
"processedAt": "2025-06-05T11:26:16.354Z",
"source": {
"dirname": "remote-ftp/test/01JJYJ0GGVZD5GR230YP6G3MEA/fromPartner",
"name": "Test_Dental.1234567.835"
},
"artifacts": [
{
"artifactType": "application/edi-x12",
"url": "https://core.us.stedi.com/2023-08-01/executions/7590afcd-26d7-4182-a8fc-1d1051e2815c/input",
"usage": "input",
"model": "execution"
}
],
"connectionId": "01JJYJ0GGVZD5GR230YP6G3MEA",
"partnership": {
"partnershipId": "stedi-test_dentalpartner",
"partnershipType": "x12",
"receiver": {
"profileId": "stedi-test"
},
"sender": {
"profileId": "dentalpartner"
}
},
"errors": [
{
"message": "String element BPR-10 must have a length of 10, actual length is 5\nElement PER-02 is not used by this guide",
"faultCode": "FAILED_TO_TRANSLATE"
}
],
"x12": {
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "1",
"controlNumber": 56199839
}
},
"receiver": {
"isa": {
"qualifier": "30",
"id": "117151744"
}
},
"sender": {
"isa": {
"qualifier": "ZZ",
"id": "900117186"
}
}
}
}
}
}
```
### Event filters
You may want to further filter the events Stedi sends to your endpoint:
* **Transaction:** This is useful if you want to send events for 277CA claim acknowledgments to one endpoint and events for 835 ERAs to another. For example, if you set this to `835: Health Care Claim Payment/Advice`, Stedi only sends events for processed 835 ERAs to your endpoint.
* **Partnership:** This is useful if you want to send test claims to one endpoint and production claims to another. For example, if you set this to `local-clearinghouse-test`, Stedi only sends events for test claims to your endpoint.
The **Guide**, **Connection**, and **Mode** filters are not relevant to claims
processing.
### Event schema
All Stedi events follow a standard JSON Schema. The event payload itself does not include the contents of a given file or transaction. Instead, it references an API path to retrieve the entire object.
```json JSON event structure example
{
"version": "0",
"id": "8a9fc08a-24b2-4eeb-af7c-f96376ea471e",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2021-11-12T00:00:00Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/transactions/3543b3f7-0d78-48cc-97c3-ac145e250a1d"
],
"detail": { ... }
}
```
In addition to their `version`, `id`, and `time`, events have the following properties:
* **`detail-type`** - Indicates the type of event, such as `transaction.processed.v2` or `file.failed.v2`.
* **`source`** - Indicates the component that generated the event. All events use `source: “stedi.core”`.
* **`account`** - The account ID that generated the event.
* **`region`** - The AWS region where the event was generated.
* **`resources`** - The URL to the resource that Stedi created. This could be a transaction or a file execution, depending on the event type. Hitting the URL with your API key is equivalent to calling the [Get Execution](/api-reference/edi-platform/core/get-executions) and [Get Transaction](/api-reference/edi-platform/core/get-transactions) endpoints.
* **`detail`** - The JSON payload. The schema for each payload is determined by the `detail-type`.
## HTTP response codes
Stedi considers a `2xx` response a success, and marks any other response as a failure.
Stedi retries events associated with status codes other than `2xx` for up to 4 times with a 90 second wait period inbetween retries.
If the maximum number of retries has been exhausted, Stedi adds the event to the [error queue](#error-queue) for the webhook.
You can set the **Concurrency** when configuring the webhook to prevent throttling. This setting determines the maximum number of deliveries that Stedi will attempt to deliver to the endpoint at one time.
## Certificates
Webhooks only support valid, publicly trusted certificates. Self-signed certificates or certificates from private certificate authorities aren't supported.
You'll receive the following error if the endpoint configured for the webhook uses a certificate that isn't signed by a known, trusted certificate authority:
```
"awsResponse": "Unable to invoke ApiDestination endpoint: API destination endpoint cannot be reached."
```
## Timeouts
The target endpoint must respond with a `2xx` status code within 5 seconds, or the event will be counted as a failed delivery.
This is a hard limit that cannot be increased or configured.
Because of this timeout limitation, we recommend designing your webhook endpoints to immediately acknowledge receipt with a `2xx` response, then process the data asynchronously. See [Best practices for webhook endpoints](#best-practices-for-webhook-endpoints).
## Retries and duplicate deliveries
When a delivery fails, Stedi will retry up to 4 times every 90 seconds. After the fifth retry, Stedi moves the event to the error queue.
If your webhook doesn't respond within 5 seconds, Stedi marks that as a failure and then automatically retries. This can result in duplicate deliveries.
We strongly recommend using idempotency in your webhook receivers to safely handle duplicate deliveries. See [Best practices for webhook endpoints](#best-practices-for-webhook-endpoints).
## Error queue
Each webhook includes an error queue. Each item in the queue consists of the original event that was attempted to be delivered. This ensures if the target service has some downtime, or anything else goes wrong, the missed events can be retried later. The error queue retains items for 14 days.
The order of the error queue is not guaranteed. The downstream service must be designed to be idempotent to handle at-least-once delivery of events, and must accept events out of order.
## Logs
To view logs, click the webhook to go to its detail page, and then navigate to the **Logs** tab.
## Deauthorized connections
If a webhook sends a message to an endpoint that returns a 401 (Unauthorized) response, the destination will be 'deauthorized'. In this state, the webhook won't be able to deliver messages.
If there is an issue with your authentication information (such as the password, API key, or OAuth settings), edit the webhook to fix it.
If the authentication information is correct, and there was a different reason for the endpoint returning a 401, you can try again by adding a temporary header. For example, `x-stedi-reauthorize` with today's date as a value. When you save, the webhook will attempt to deliver again. This header can be removed later. Editing the value of a header will also restart deliveries.
You will likely have a queue of messages to deliver, so Stedi will automatically start retrying them after you make this change. If the endpoint is still returning an invalid response, the webhook will return to `Deauthorized`.
## Best practices for webhook endpoints
When creating endpoints to receive webhooks from Stedi, we recommend the following architecture:
1. **Acknowledge first, process later**: Design your endpoint to immediately return a `2xx` status code to acknowledge receipt, then process the payload asynchronously.
2. **Store payloads for processing**: Capture the webhook data in a queue, database, or other storage mechanism before processing.
3. **Process asynchronously**: Handle the actual business logic in a separate process or worker after acknowledging receipt.
4. **Implement idempotency**: Use idempotency keys from the event payload to prevent duplicate processing.
* Store the `eventId` from each webhook payload in your database
* Before processing an incoming webhook, check if its `eventId` has already been processed
* Design operations to be idempotent, ensuring that processing the same event multiple times doesn't cause issues (e.g., avoid incrementing counters on each processing attempt)
This architecture prevents [timeouts](#timeouts), handles potential duplicate deliveries, and allows you to process high volumes of events.
# Coordination of benefits (COB) checks
Source: https://www.stedi.com/docs/healthcare/coordination-of-benefits
***
title: Coordination of benefits (COB) checks
sidebarTitle: 'Coordination of benefits checks'
-----------------------------------------------
Some patients have multiple health plans. For example, a dependent may have coverage with two private insurance companies through their parents. When a patient has active coverage with multiple plans, you need to know which health plan is primarily responsible for paying claims (coordination of benefits).
You can use a coordination of benefits (COB) check to determine:
* If a patient is covered by more than one health plan
* Whether there is coverage overlap between plans
* Whether coverage overlap requires coordination of benefits
* Each payer's responsibility for payment (primacy) in coordination of benefits scenarios
COB checks can help ensure that you submit claims to the correct payer and avoid claim denials. We recommend performing COB checks for all new patients who have coverage through one of Stedi’s supported payers. When Stedi identifies overlapping coverage, we strongly recommend performing follow-up [eligibility checks](/healthcare/send-eligibility-checks) with each payer to verify coverage status and retrieve the patient's complete and current benefits information before you submit claims.
COB checks require that you know at least one of the patient's active health
plans. If you're unsure whether a patient has any active coverage at all, you
can perform an [insurance discovery check](/healthcare/insurance-discovery) to
find potential coverage.
## Supported payers
COB doesn't support Medicare plans. However, most Medicare Advantage plans are supported. Visit the [Payer Network](https://www.stedi.com/healthcare/network?query=eyIyNzAiOnt9LCIyNzYiOnt9LCI4MzUiOnt9LCI4MzdQIjp7fSwiODM3SSI6e30sIjgzN0QiOnt9LCJDT0IiOnsiaXNTdXBwb3J0ZWQiOnRydWV9fQ%3D%3D\&page=0) for a complete list of supported payers.
## How COB checks work
You submit a coordination of benefits request with information for one of the patient's health plans. The information required is similar to a standard eligibility check – first name, last name, DOB, and either member ID or SSN – and you should first run a [real-time eligibility check](https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-eligibility) to ensure that the member’s details are accurate.
Once you submit the request, Stedi searches a database of eligibility data from regional and national plans. This database has 245+ million patient coverage records from 45+ health plans, ASOs, TPAs, and others, including participation from the vast majority of national commercial health plans. Data is updated at least weekly to ensure accuracy.
Stedi synchronously returns summary information about each of the patient’s active health plans, whether there is coverage overlap, and, if so, the responsibility sequence number for each payer (such as primary or secondary, if that can be determined).
Once you receive the results, we strongly recommend performing follow-up [eligibility checks](/healthcare/send-eligibility-checks) with each payer to verify coverage status and retrieve the patient's complete and current benefits information before you submit claims.
## Check COB
Each COB check must be for a participating health plan for which the patient has coverage. For example, if the patient has coverage from Cigna and UnitedHealthcare, a COB check to Aetna will return an error.
Medicare and Medicare Advantage plans are not supported.
### Accurate patient data
COB checks are significantly more sensitive to data accuracy than eligibility checks. To perform successful COB checks, the patient information you provide in the check **must** match the payer's data exactly.
For example, if a payer has a patient's name stored as "Jonathan Doe", they may return benefits information when you submit an eligibility check for "Jon Doe", as long as they can identify the patient through the other information provided. However, a COB request for "Jon Doe" will fail because the name doesn't match the payer's records exactly.
To avoid unnecessary COB check failures, we strongly recommend that you first submit an eligibility check request for the patient. Then use the following data from the successful eligibility response to build the COB request: `firstName`, `lastName`, `dateOfBirth`, `memberId`.
### Service type code
You can submit COB checks with the `30` service type code for Health Benefit Plan Coverage. This is the broadest service type code that covers all medical services and subtypes included in the patient's health plan.
### API submission
Use the [Coordination of Benefits Check](/api-reference/healthcare/post-coordination-of-benefits) endpoint to submit COB checks programmatically. The information required in the request is similar to a standard eligibility check – first name, last name, DOB, and either member ID or SSN.
The following example shows a COB check for a dependent named Jordan Doe who has coverage with Blue Cross Blue Shield of Massachusetts (Stedi payer ID: `EWDCI`).
```bash
curl --request POST \
--url "https://healthcare.us.stedi.com/2024-04-01/coordination-of-benefits" \
--header "Authorization: " \
--header "Content-Type: application/json" \
--data "'{
"tradingPartnerServiceId": "EWDCI",
"provider": {
"organizationName": "ACME Health Services",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1985-05-27",
"memberId": "W000000000"
},
"dependent": {
"firstName": "Jordan",
"lastName": "Doe",
"dateOfBirth": "2002-12-31"
},
"encounter": {
"dateOfService": "2024-08-02",
"serviceTypeCode": "30"
}
}'"
```
Visit [Request and response examples](/healthcare/cob-response#request-and-response-examples) to review sample COB checks for common scenarios.
#### Concurrency limit
Visit [Concurrency limits](/api-reference#concurrency-limits) for more information.
### Manual submission
To prevent accidentally sending checks to unsupported payers, the Stedi portal only provides the option to perform a COB check within successful eligibility checks to supported COB payers.
To submit a new COB check through the Stedi portal:
1. Go to the [Eligibility searches](https://portal.stedi.com/app/healthcare/eligibility) page.
2. Click the eligibility check for the patient you want to check for coordination of benefits. This must be a successful eligibility check for the patient's health plan - failed checks can't be used as the basis for COB checks.
3. Click **View** to review the details of the eligibility check.
4. Click `New COB check` to open the coordination of benefits check form. Stedi prefills the patient's information from the eligibility check.
# Credentialing and enrollment
Source: https://www.stedi.com/docs/healthcare/credentialing-and-enrollment
***
## title: Credentialing and enrollment
Healthcare providers must complete three distinct enrollment processes to work with payers and send transactions through clearinghouses:
* **Credentialing:** Validating a healthcare provider's qualifications
* **Payer enrollment:** Registering a credentialed provider with a specific payer's health plan(s)
* **Transaction enrollment:** Registering a provider to send and receive EDI transactions (such as claims and eligibility checks) through a specific clearinghouse with a specific payer
These enrollments typically happen in sequence: first credentialing, then payer enrollment, and then transaction enrollment, although credentialing and payer enrollment are sometimes combined into a single process. Stedi specifically handles [transaction enrollment](/healthcare/transaction-enrollment), the final step needed to exchange eligibility and claims transactions through our clearinghouse.
## Credentialing
Credentialing is the process of validating a healthcare provider's qualifications, including:
* Verification of education, training, and licensure
* Review of board certifications and medical specialties
* Confirmation of work history and malpractice insurance
* Review of any sanctions, restrictions, or malpractice claims
Credentialing establishes that a provider meets the payer's standards for providing care to their members. Once credentialed, a provider becomes eligible to join the payer's networks. Some payers have multiple networks and those networks may contain multiple tiers of providers. In order to actually join a network, the payer may require the provider to agree to a rate schedule and sign a contract with other terms.
**Timeline:** Credentialing typically takes 90-180 days to complete.
**Who handles it:** Providers must complete credentialing directly with each payer or through a specialized credentialing service. **Stedi doesn't handle the credentialing process.**
## Payer enrollment
Payer enrollment (also called provider enrollment) is the process of registering a credentialed provider with a specific payer's health plan(s). This involves:
* Submitting applications to payers for specific lines of business (Medicare, Medicaid, commercial plans)
* Providing information about the provider's practice, such as locations and billing details
* Establishing contract terms for services and reimbursement rates
* Setting up payment arrangements
Payer enrollment establishes a business relationship between the provider and the payer. Once enrolled, the provider can submit claims to the payer and receive payments for services provided to the payer's members. (Payers might also accept at least certain types of claims from non-enrolled providers subject to legal requirements and plan rules.)
**Timeline:** Payer enrollment typically takes 60-120 days after credentialing is complete. However, this process is sometimes combined with or conducted in parallel with the credentialing process.
**Who handles it:** Providers must complete payer enrollment directly with each payer. **Stedi doesn't handle the payer enrollment process.**
## Transaction enrollment
Transaction enrollment is the process of registering a provider to send and receive electronic EDI transactions (such as claims and eligibility checks) through a specific clearinghouse with a specific payer. Once enrolled, the provider can send and receive specific transactions with the payer through the clearinghouse.
Transaction enrollment involves:
* Submitting the provider's name, tax ID (EIN / TIN), NPI, billing address, and contact information
* Specifying which transaction types, such as claims, eligibility checks, and Electronic Remittance Advice (ERAs), the provider wants to exchange electronically
* Setting up the necessary technical connections between the clearinghouse and payer
All payers require providers to complete transaction enrollment before receiving ERAs because ERAs can only be sent to a single clearinghouse. When you submit an ERA enrollment in Stedi, it overrides the provider's existing ERA routing.
A much smaller number of payers also require transaction enrollment before providers can start submitting other transaction types, such as claims and eligibility checks.
**When it's required:** Check the [Payer Network](https://www.stedi.com/healthcare/network) to determine whether your payers require enrollment for the transaction types you want to send and receive. If the network says enrollment isn't required, then you can start sending those transactions right away - no transaction enrollment needed. However, you'll still need to include the provider's information (like their [NPI](/healthcare/national-provider-identifier)) in API requests when required.
**Timeline:** Transaction enrollment typically takes 2-6 weeks, depending on the payer.
**Who handles it:** Stedi handles the transaction enrollment process on behalf of providers. Visit [Transaction enrollment](/healthcare/transaction-enrollment) to learn how to complete transaction enrollment through Stedi.
Transaction enrollment is specific to each clearinghouse. If you switch from another clearinghouse to Stedi, you'll need to complete transaction enrollment through Stedi even if you were previously enrolled with the same payer through a different clearinghouse.
# Active coverage
Source: https://www.stedi.com/docs/healthcare/eligibility-active-coverage-benefits
***
title: 'Active coverage'
sidebarTitle: 'Active coverage'
-------------------------------
After you send a successful eligibility or insurance discovery check, the payer sends back an X12 271 eligibility response containing the patient’s benefits information. Stedi transforms the 271 response from the original X12 EDI into JSON, making it easier to read, understand, and ingest into your system.
You can find the full benefits response shape in the [Real-Time Eligibility Check](/api-reference/healthcare/post-healthcare-eligibility) and [Insurance Discovery Check](/api-reference/healthcare/post-insurance-discovery) API references. This documentation describes how to use the eligibility response to determine the patient's active coverage, plan details, and specific benefits.
## Does the patient have coverage for the requested service?
You need two key pieces of information to determine whether the patient's health plan covers the requested service. The patient has coverage when:
1. The date of service is within the [eligibility period](#when-is-the-patient-eligible-for-benefits%3F) for their health plan.
2. They have [active coverage](#active-and-inactive-coverage) for the applicable [service type code](#service-type-codes).
Once you know that the patient has coverage, you can determine [patient responsibility](/healthcare/eligibility-patient-responsibility-benefits), or how much the patient will pay for the service. For example, you can determine the patient's co-payment, deductible, and out-of-pocket maximum.
## When is the patient eligible for benefits?
The `planDateInformation` object contains dates related to the patient's coverage under their health plan. Most commercial payers only return information for the current calendar year.
You can use these dates to determine the patient's eligibility for benefits.
* The dates in `planDateInformation` apply to every benefit within the patient's health plan unless specifically overridden within a `benefitsInformation.benefitsDateInformation` object. Visit [Benefit-specific eligibility dates](#benefit-specific-eligibility-dates) for more details.
* The patient likely doesn't have active coverage if the date of service is after the earliest ending `plan`, `eligibility` `planEnd`, `eligibilityEnd`, `policyEffective`, or `policyExpiration` value.
The following example shows part of the benefits response for a health plan that began on January 1, 2024 and ended on December 31, 2024. The patient was eligible for benefits under that health plan starting on January 2, 2024.
{/* schema:PlanDateInformation:unwrap */}
```json
"planDateInformation": {
"planBegin": "20240101",
"planEnd": "20241231",
"eligibilityBegin": "20240102"
}
```
### Plan dates for dependents
Dependents can have different coverage dates than the subscriber due to qualifying life events, such as starting a new job or passing the age limit for coverage through their parent's plan.
When the patient is a dependent, and the payer sends back date(s) that are different for the subscriber and dependent, Stedi includes only the dates for the dependent and omits the subscriber's date(s).
## What are the patient's benefits?
The vast majority of the information you need to determine a patient's benefits under their health plan is contained in the `benefitsInformation` array. Each object in this array contains information about a specific benefit type, such as co-payments, deductibles, and exclusions.
The `benefitsInformation.code` property indicates the type of benefits information described in the `benefitsInformation` object. Sometimes, the code simply indicates that the patient has active coverage for the `serviceTypes` listed. For example, the following excerpt shows a member with active coverage for service type code `30` (Health Benefit Plan Coverage).
{/* schema:BenefitsInformation */}
```json
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"30"
],
"serviceTypes": [
"Health Benefit Plan Coverage"
],
"planCoverage": "Open Access Plus",
"additionalInformation": [
{
"description": "Complete Care Management"
}
]
}
```
In other array entries, the code indicates that the `benefitsInformation` object contains details about specific benefits, such as co-payments, deductibles, and exclusions.
The following example shows a patient's co-payment for psychiatric, psychotherapy, and social work in-office visits.
* The copayment is $20 for providers considered in-network, as indicated by the `Y` in the `inPlanNetworkIndicatorCode` property.
* Note that the `inPlanNetworkIndicatorCode` doesn't tell you whether the provider that requested the eligibility check is in-network for the health plan, so you shouldn't assume a $20 copay for that provider until you can verify that they are in-network. Visit [Provider network status, authorizations, referrals](/healthcare/eligibility-network-status-authorization-referrals) for more details about verifying a provider's network status.
{/* schema:BenefitsInformation */}
```json
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"industryCode": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"industryCode": "Office"
}
]
}
```
### Active and inactive coverage
You can quickly determine whether a patient has active coverage for specific service types when the `benefitsInformation.code` is set to `1` (Active Coverage). The following example shows a member with active coverage for service type code `30` (Health Benefit Plan Coverage).
{/* schema:BenefitsInformation */}
```json
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"30"
],
"serviceTypes": [
"Health Benefit Plan Coverage"
],
"insuranceTypeCode": "C1",
"insuranceType": "Commercial",
"planCoverage": "Gold Plan HMO",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsRelatedEntity": {
"entityIdentifier": "Payer",
"entityType": "Non-Person Entity",
"entityName": "UNITEDHEALTHCARE",
"entityIdentification": "PI",
"entityIdentificationValue": "87726"
}
}
```
Likewise, you can quickly determine when a patient has inactive coverage for a service type when the `benefitsInformation.code` is set to `6` (Inactive). The following example shows a member with inactive coverage for service type code `30` (Health Plan Benefit Coverage).
{/* schema:BenefitsInformation */}
```json
{
"code": "6",
"name": "Inactive",
"serviceTypeCodes": [
"30"
],
"serviceTypes": [
"Health Benefit Plan Coverage"
],
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable"
}
```
### Benefit type codes
The benefit type code indicates the type of benefit described in the `benefitsInformation` object, such as co-payments, deductibles, and exclusions. The benefit type code is different from the service type code, which indicates the type of service covered by the benefit. Payers may send multiple `benefitsInformation` objects for the same service type code with different benefit type codes to communicate different aspects of the benefits.
The following is a complete list of codes that can be returned in the `benefitsInformation.code` property.
* `1` - Active Coverage
* `2` - Active - Full Risk Capitation
* `3` - Active - Services Capitated
* `4` - Active - Services Capitated to Primary Care Physician
* `5` - Active - Pending Investigation
* `6` - Inactive
* `7` - Inactive - Pending Eligibility Update
* `8` - Inactive - Pending Investigation
* `A` - [Co-Insurance](/healthcare/eligibility-patient-responsibility-benefits#co-insurance)
* `B` - [Co-Payment](/healthcare/eligibility-patient-responsibility-benefits#co-payment)
* `C` - [Deductible](/healthcare/eligibility-patient-responsibility-benefits#deductible)
* `CB` - Coverage Basis
* `D` - Benefit Description
* `E` - Exclusions
* `F` - Limitations
* `G` - [Out of Pocket (Stop Loss)](/healthcare/eligibility-patient-responsibility-benefits#out-of-pocket-stop-loss)
* `H` - Unlimited
* `I` - Non-Covered
* `J` - [Cost Containment](/healthcare/eligibility-patient-responsibility-benefits#cost-containment)
* `K` - Reserve
* `L` - Primary Care Provider
* `M` - Pre-existing Condition
* `MC` - Managed Care Coordinator
* `N` - Services Restricted to Following Provider
* `O` - Not Deemed a Medical Necessity
* `P` - Benefit Disclaimer
* `Q` - Second Surgical Opinion Required
* `R` - Other or Additional Payor
* `S` - Prior Year(s) History
* `T` - Card(s) Reported Lost/Stolen | Typically used by Medicaid to indicate to a provider that the person who has presented the ID card is using a stolen ID card.
* `U` - Contact Following Entity for Eligibility or Benefit Information
* `V` - Cannot Process
* `W` - Other Source of Data
* `X` - Health Care Facility
* `Y` - [Spend Down](/healthcare/eligibility-patient-responsibility-benefits#spend-down)
#### Code `V` - Cannot Process
These are the most common reasons a payer may return a `benefitsInformation.code` of `V`:
* **Request errors:** The payer didn't actually return any benefits information because of errors in the request - listed in the `errors` object. You should ignore the stub benefits data in the `benefitsInformation` object, correct the errors, and resubmit the eligibility check.
* **Wrong submission method:** The payer doesn't support automated X12 EDI eligibility checks for the service type code you provided and requires that you obtain benefits information through a different channel, such as by phone or online portal. The `benefitsInformation.additionalInformation.description` typically contains an explanation. The payer may also include contact information in `payer.contactInformation`.
* **Unable to interpret:** The payer located the member but couldn't make sense of the request. For example, a dental payer can't return benefits information for a vision service type code.
* **Alternate service type code:** The payer has grouped the service type code you submitted into a different one. In this case, the payer typically returns a `benefitsInformation` entry with `code` = `V` immediately followed by an entry with an active code and `benefitsInformation.serviceTypeCodes` set to the preferred service type code.
### Service type codes
The `benefitsInformation.serviceTypeCodes` property contains the service type codes (STCs) that apply to the benefit.
You should review the [STC list](/healthcare/eligibility-stc-procedure-codes#full-stc-list) to determine which STCs are relevant to the benefits you're interested in and check for all of them in the response. This is helpful because the payer may return relevant benefits under a different STC than the one you submitted. For example, mental health benefits are typically returned with STC `MH` (Mental Health), but some payers may use other STCs, such as `BH` (Behavioral Health), `A4` (Psychiatric) or `SA` (Substance Abuse) for related services.
You should also check all `benefitsInformation` objects with relevant `serviceTypeCodes` values because the same STC is typically repeated across multiple `benefitsInformation` objects in the response.
* Each object communicates a different aspect of benefits, such as coverage status, co-pays, or deductibles.
* Payers also use multiple objects to describe different subsets of services within an STC. For example, the `MH` STC might have one entry for standard therapy and another that notes coverage for other treatments. Descriptions typically appear in entries with code: `"1" (Active Coverage)` or code: `"D" (Benefit Description)`, but they can appear in other entries as well.
**Example**
The following three `benefitsInformation` objects all have the same `serviceTypeCodes` value of `CF`, which corresponds to `Mental Health Provider - Outpatient`. However, the `code` property is different for each object, indicating that they describe different aspects of the benefits:
* The first object has `code` = `1`, indicating that the patient has active coverage for outpatient mental health services.
* The second object has `code` = `C`, indicating that the patient has a $1000 deductible for outpatient mental health services.
* The third object has `code` = `D`, indicating that the patient has a benefit description that qualifies the coverage for outpatient mental health services.
{/* schema:BenefitsInformation:unwrapArray */}
```json
"items": [
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["CF"],
"serviceTypes": [
"Mental Health Provider - Outpatient"
],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "INCLUSIONS SPEECH/PHYSICAL/OCCUPATIONAL THERAPY; APPLIED BEHAVIOR ANALYSIS (ABA)"
}
]
},
{
"code": "C",
"name": "Deductible",
"serviceTypeCodes": ["CF"],
"serviceTypes": [
"Mental Health Provider - Outpatient"
],
"benefitAmount": "1000",
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes"
},
{
"code": "D",
"name": "Benefit Description",
"serviceTypeCodes": ["CF"],
"serviceTypes": [
"Mental Health Provider - Outpatient"
],
"additionalInformation": [
{
"description": "EXCLUSIONS: DEVELOPMENTAL TESTING, EDUCATIONAL THERAPY"
}
]
}
]
```
### Benefit-specific eligibility dates
When present, the `benefitsInformation.benefitsDateInformation` object contains dates that determine the patient's eligibility for a specific type of benefits. You should use these dates to determine the patient's eligibility for that specific benefit type instead of the dates in the `planDateInformation` object.
Payers send benefit-specific dates when certain benefits within a plan have different activation rules or waiting periods than the overall plan coverage. This can happen in a variety of scenarios, including:
* Employers may offer plans with benefits that activate based on employment duration or role. For example, Medical coverage may start on your hire date, but life insurance or disability coverage begins after 90 days.
* Some plans require a delay before certain benefits start, even though your general plan is active. For example, dental insurance may have a 6-month waiting period for major services (like crowns), but basic services (like cleanings) are covered immediately.
* Some government programs like Medicare split coverage (Part A, B, D, etc.), each with its own effective date.
* You may switch plans during open enrollment, and new benefits might have different effective dates.
## Does the patient have carveout benefits?
A carveout is when the primary payer for a plan lets another entity handle certain benefits. Carveout administrators often specialize in benefits for a particular service, such as mental health services or pharmacy benefits. For example, many Blue Cross Blue Shield (BCBS) plans carve out mental (behavioral) health benefits to Magellan, a mental health payer.
Carveouts are part of a single health plan, so they're different from secondary or tertiary insurance coverage. A patient can have carveout benefits for their primary plan and still have secondary insurance coverage through other payers.
Most payers omit carveout benefits from eligibility responses, but many include the carveout administrator's information.
### Carveout administrator information
Don't rely on `benefitsRelatedEntities.entityIdentifier` to identify carveout administrators because the value can vary between payers.
Instead, look for a `benefitsInformation` object that has:
* `code` = `U` (Contact Following Entity for Eligibility or Benefit Information) or `code` = `1` (Active coverage).
* `serviceTypeCodes` with [related STCs](#service-type-codes).
* a `benefitsRelatedEntities` object containing contact information. If present, `benefitsRelatedEntities.entityIdentificationValue` contains the patient's member ID for the carveout administrator.
You should also examine `benefitsInformation` objects with `code` = `D` (Benefit Description). The `additionalInformation.description` property may contain relevant details.
The following example shows a benefits response for a patient whose mental health benefits (`serviceTypeCodes` = `MH`) are handled by a third-party administrator called Acme Health Payer. The `description` property in the second object indicates that these benefits are managed separately.
{/* schema:BenefitsInformation:unwrapArray */}
```json
"benefitsInformation": [
{
"code": "U",
"serviceTypeCodes": [
"MH"
],
"benefitsRelatedEntities": [
{
"entityIdentifier": "Third-Party Administrator",
"entityType": "Non-Person Entity",
"entityName": "Acme Health Payer",
"entityIdentificationValue": "123456789",
"contactInformation": {
"contacts": [
{
"communicationMode": "Telephone",
"communicationNumber": "1234567890"
}
]
}
}
]
},
{
"code": "D",
"serviceTypeCodes": ["MH"],
"additionalInformation": [
{
"description": "BEHAVIORAL HEALTH MANAGED SEPARATELY"
}
]
}
]
```
### Get carveout benefits details
When payers return carveout administrator information, you can:
1. Get the carveout administrator's payer ID from the [Payer Network](https://www.stedi.com/healthcare/network) or [Search Payers](/api-reference/healthcare/get-search-payers) endpoint.
2. Get the patient's member ID for the carveout administrator. It's in the `benefitsRelatedEntities.entityIdentificationValue` property, if present.
3. Send a second eligibility check to the carveout administrator.
If you use the right STC, many carveout admins will return the missing carveout benefits. The STC may differ from the one you sent to the primary payer. Visit [STCs and procedure codes](/healthcare/eligibility-stc-procedure-codes) for tips on choosing the right STC.
If the primary payer doesn't return the carveout administrator's details, you can try checking the patient's member ID card. The back of the card often lists the carveout administrator's name and contact information. You can also try calling the primary payer and checking their website or portal.
## What's the plan name?
The only standard property that contains a health plan product or program name is `benefitsInformation.planCoverage`.
Payers are only required to provide a plan name when returning Service Type Code (STC) `30`, but the plan name itself isn't tied to any specific STC. The `benefitsInformation` array can contain many entries for multiple plans, such as medical, dental, and vision.
For example, a payer might send back multiple `benefitsInformation` objects with STC `30`. Each one can have a different `planCoverage` value. You might see `"PPO DENTAL"` in one and `"PREFERRED PROVIDER OPTION MEDICAL"` in another. This just means the member has multiple plans – a dental plan and a medical plan. Each plan gets its own set of objects.
In the following example, the plan name is `Open Access Plus`:
{/* schema:BenefitsInformation */}
```json
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"30"
],
"serviceTypes": [
"Health Benefit Plan Coverage"
],
"planCoverage": "Open Access Plus",
"additionalInformation": [
{
"description": "Complete Care Management"
}
]
}
```
You may also be able to identify the plan name through the following properties, but they're not as reliable as `planCoverage.` Payers aren't required to return information for these properties, so behavior can vary by payer or even by plan.
* Some properties may contain a name for the group (often named for the employer if they sponsor the plan), insurance policy, or network. These properties are: `groupDescription`, `planDescription`, and `planNetworkIdDescription`. These properties may be included in the `subscriber`, `dependents`, or `benefitsInformation.benefitsAdditionalInformation` objects, depending on where the payer places this information in the benefit response.
* Some payers may send something like a plan name in `planInformation.planDescription` or as unstructured text in `benefitsInformation.additionalInformation.description`.
### BCBS home plan
Many Blue Cross Blue Shield (BCBS) payers are part of the BlueCard Program, which makes it easier to run eligibility checks for patients receiving care outside their home state. With BlueCard, you can send eligibility checks to any participating BCBS payer, and BlueCard routes them to the patient's home plan for benefits verification.
For example, if you send a request to BCBS Florida for a patient covered by BCBS Alabama, the response will include benefits information from the patient's home plan BCBS Alabama.
Stedi enriches the eligibility response with information about the patient's home plan when the eligibility check includes the member's first name, last name, birthdate, and full member ID (including the 3-character BCBS alpha prefix).
In JSON responses, Stedi returns information about the patient's home plan in a `benefitsInformation[].benefitsRelatedEntities` entry. The relevant object's `entityIdentifier` property is set to `Party Performing Verification`.
```json
"benefitsInformation": [
{
"code": "1",
"serviceTypeCodes": ["30"],
...
"benefitsRelatedEntities": [
{
"entityIdentifier": "Party Performing Verification",
"entityType": "Non-Person Entity",
"entityName": "Blue Cross Blue Shield of Alabama",
"entityIdentification": "PI",
"entityIdentificationValue": "00510BC"
}
]
},
...
]
```
In X12 EDI responses, Stedi returns this information in `Loop 2120C` (Subscriber Benefit Related Entity) or `Loop 2120D` (Dependent Benefit Related Entity), depending on whether the patient is the subscriber or a dependent. The `NM1-01` composite is set to `VER` (Party Performing Verification).
```
LS*2120~
NM1*VER*2*Blue Cross Blue Shield of Alabama*****PI*00510BC~
LE*2120~
```
BCBS enrichment isn't supported when:
* The patient's member ID doesn't contain the 3-character alpha prefix.
* The patient has stand-alone vision and pharmacy cards issued through an intermediary model.
* The patient's plan is a stand-alone dental product.
* The patient is part of a Federal Employee Program (FEP). In this case, the patient has `R` before their member ID.
## Does the patient have crossover coverage?
Crossover coverage is the process where a primary insurance payer (usually Medicare) automatically forwards claims and related information to a secondary payer (typically Medicaid or a supplemental private insurer) after processing. When there's crossover coverage, you won't need to manually resubmit claims to the secondary payer - it happens automatically.
When the patient has crossover coverage, the eligibility response may contain information about crossover carriers, such as their names and identifiers, in the `benefitsInformation.benefitsRelatedEntities` array. However, you **shouldn't** automatically assume the responding payer will automatically forward crossover claims to those payers.
To determine whether a claim has been sent to a crossover carrier, you must review the 835 ERA. Visit [crossover claims](/healthcare/receive-claim-responses#crossover-claims) for more details.
## Does the patient have a Medicare Advantage plan?
A Medicare Advantage plan (also known as Medicare Part C) is a type of health plan offered by private insurance companies approved by Medicare. It provides all the benefits of standard Medicare (Parts A and B) and often includes additional services such as prescription drug coverage, vision, dental, and hearing care. Medicare Advantage plans also include an annual out-of-pocket spending limit, offering financial protection beyond what standard Medicare provides.
### Commercial payer responses
A response from a commercial payer likely contains a Medicare Advantage plan when it has any of the following properties:
* `benefitsInformation.insuranceTypeCode` = `MA` or `MB` which correspond to `benefitsInformation.insuranceType` = `Medicare Part A` and `Medicare Part B`, respectively.
* `planInformation.hicNumber` and/or `benefitsInformation.benefitsAdditionalInformation.hicNumber`. These properties contain the Medicare Beneficiary Identifier (MBI), so if either of these are present, then it's almost certainly a Medicare Advantage plan.
Behavior varies by payer, so these properties may not always be included, even if the patient has a Medicare Advantage plan.
### CMS responses
A response from CMS likely contains a Medicare Advantage plan when it has the following properties:
* `benefitsInformation.code` = `U` (which corresponds to `benefitsInformation.name` = `Contact Following Entity for Eligibility or Benefit Information`) combined with `serviceTypeCodes` = `30`.
* `benefitsInformation.additionalInformation.description` - CMS provides what they call the MA Bill Option Code in this property.
The MA Bill Option code may be one of two sets of values, depending on whether the Medicare beneficiary is locked in. When a Medicare beneficiary is locked in, they can only make changes to their coverage during specific times of the year, unless they qualify for a Special Enrollment Period (SEP).
In the following code sets, the Fiscal Intermediary is what CMS refers to as a MAC.
**Medicare Beneficiary locked in to Medicare Advantage (MA)**
* `A`: Fiscal Intermediary should process all claims
* `B`: MA should process only in-plan Part A claims and in-area Part B claims
* `C`: MA should process all claims
**Medicare Beneficiary NOT locked in to Medicare Advantage (MA)**
* `1`: Fiscal Intermediary should process all claims
* `2`: MA should process only in-plan Part A claims and in-area Part B claims
# Eligibility code lists
Source: https://www.stedi.com/docs/healthcare/eligibility-code-lists
***
title: Eligibility code lists
sidebarTitle: 'Code lists'
--------------------------
You may need to reference the following code lists when submitting eligibility checks through Stedi. Note that this page doesn’t contain every code list in the eligibility request and response; it only contains code lists that are too long to represent clearly within the [API reference documentation](/api-reference/healthcare/post-healthcare-eligibility).
## Delivery Frequency Codes
Returned in the `benefitsInformation.benefitsServiceDelivery.deliveryOrCalendarPatternCode` property. This code specifies the routine shipments, deliveries, or calendar pattern.
* `1` - 1st Week of the Month
* `2` - 2nd Week of the Month
* `3` - 3rd Week of the Month
* `4` - 4th Week of the Month
* `5` - 5th Week of the Month
* `6` - 1st & 3rd Weeks of the Month
* `7` - 2nd & 4th Weeks of the Month
* `8` - 1st Working Day of Period
* `9` - Last Working Day of Period
* `A` - Monday through Friday
* `B` - Monday through Saturday
* `C` - Monday through Sunday
* `D` - Monday
* `E` - Tuesday
* `F` - Wednesday
* `G` - Thursday
* `H` - Friday
* `J` - Saturday
* `K` - Sunday
* `L` - Monday through Thursday
* `M` - Immediately
* `N` - As Directed
* `O` - Daily Mon. through Fri.
* `P` - 1/2 Mon. & 1/2 Thurs.
* `Q` - 1/2 Tues. & 1/2 Thurs.
* `R` - 1/2 Wed. & 1/2 Fri.
* `S` - Once Anytime Mon. through Fri.
* `SG`- Tuesday through Friday
* `SL` - Monday, Tuesday and Thursday
* `SP` - Monday, Tuesday and Friday
* `SX` - Wednesday and Thursday
* `SY` - Monday, Wednesday and Thursday
* `SZ` - Tuesday, Thursday and Friday
* `T` - 1/2 Tue. & 1/2 Fri.
* `U` - 1/2 Mon. & 1/2 Wed.
* `V` - 1/3 Mon., 1/3 Wed., 1/3 Fri.
* `W` - Whenever Necessary
* `X` - 1/2 By Wed., Bal. By Fri.
* `Y` - None (Also Used to Cancel or Override a Previous Pattern)
## Delivery Pattern Time Codes
Returned in the `benefitsInformation.benefitsServiceDelivery.deliveryPatternTimeQualifierCode` property. This code specifies the time for routine shipments or deliveries.
* `A` - 1st Shift (Normal Working Hours)
* `B` - 2nd Shift
* `C` - 3rd Shift
* `D` - A.M.
* `E` - P.M.
* `F` - As Directed
* `G` - Any Shift
* `Y` - None (Also Used to Cancel or Override a Previous Pattern)
## Eligibility and benefit type codes
Returned in the `benefitsInformation.code` property. Visit [Determine patient benefits](/healthcare/eligibility-active-coverage-benefits#benefit-type-codes) for a complete list.
## Employment Status Codes
Returned in the `subscriber.employmentStatusCode` and `dependents.employmentStatusCode` properties. These codes indicate the employment status of the subscriber or dependent as it relates to military service.
* `AE` - Active Reserve
* `AO` - Active Military - Overseas
* `AS` - Academy Student
* `AT` - Presidential Appointee
* `AU` - Active Military - USA
* `CC` - Contractor
* `DD` - Dishonorably Discharged
* `HD` - Honorably Discharged
* `IR` - Inactive Reserves
* `LX` - Leave of Absence: Military
* `PE` - Plan to Enlist
* `RE` - Recommissioned
* `RM` - Retired Military - Overseas
* `RR` - Retired Without Recall
* `RU` - Retired Military - USA
## Government Service Affiliation Codes
Returned in the `subscriber.governmentServiceAffiliationCode` and `dependent.governmentServiceAffiliationCode` properties. These codes indicate the government service affiliation of the subscriber or dependent as it relates to military service.
* `A` - Air Force
* `B` - Air Force Reserves
* `C` - Army
* `D` - Army Reserves
* `E` - Coast Guard
* `F` - Marine Corps
* `G` - Marine Corps Reserves
* `H` - National Guard
* `I` - Navy
* `J` - Navy Reserves
* `K` - Other
* `L` - Peace Corp
* `M` - Regular Armed Forces
* `N` - Reserves
* `O` - U.S. Public Health Service
* `Q` - Foreign Military
* `R` - American Red Cross
* `S` - Department of Defense
* `U` - United Services Organization
* `W` - Military Sealift Command
## Identification Code Qualifiers
Returned in the `benefitsInformation.benefitsRelatedEntities.entityIdentification` object. This property designates the type of identifier in the `benefitsInformation.benefitsRelatedEntities.entityIdentificationValue` property.
* `24` - Employer's Identification Number
* `34` - Social Security Number
* `46` - Electronic Transmitter Identification Number (ETIN)
* `FA` - Facility Identification
* `FI` - Federal Taxpayer's Identification Number
* `II` - Standard Unique Health Identifier for each Individual in the United States
* `MI` - Member Identification Number
* `NI` - National Association of Insurance Commissioners (NAIC) Identification
* `PI` - Payor Identification
* `PP` - Pharmacy Processor Number
* `SV` - Service Provider Number
* `XV` - Centers for Medicare and Medicaid Services PlanID
* `XX` - Centers for Medicare and Medicaid Services National Provider Identifier
## Industry Codes
Returned in the `benefitsInformation.eligibilityAdditionalInformation.industryCode` property when `benefitsInformation.eligibilityAdditionalInformationList.codeListQualifierCode` is set to `ZZ` - Mutually defined.
Visit the Centers for Medicare and Medicaid Services [Place of Service Code Set](https://www.cms.gov/medicare/coding-billing/place-of-service-codes/code-sets) for a complete list of codes and descriptions.
## Information Status Codes
Returned in the `subscriber.informationStatusCode` and `dependents.informationStatusCode` properties. These codes are used to report military service data.
* `A` - Partial
* `C` - Current
* `L` - Latest
* `O` - Oldest
* `P` - Prior
* `S` - Second Most Current
* `T` - Third Most Current
## Insurance Type Codes
Returned in the `benefitsInformation.insuranceTypeCode` property. These codes indicate the type of insurance policy within a specific insurance program.
* `12` - Medicare Secondary Working Aged Beneficiary or Spouse with Employer Group Health Plan
* `13` - Medicare Secondary End-Stage Renal Disease Beneficiary in the Mandated Coordination Period with an Employer's Group Health Plan
* `14` - Medicare Secondary, No-fault Insurance including Auto is Primary
* `15` - Medicare Secondary Worker's Compensation
* `16` - Medicare Secondary Public Health Service (PHS) or Other Federal Agency
* `41` - Medicare Secondary Black Lung
* `42` - Medicare Secondary Veteran's Administration
* `43` - Medicare Secondary Disabled Beneficiary Under Age 65 with Large Group Health Plan (LGHP)
* `47` - Medicare Secondary, Other Liability Insurance is Primary
* `AP` - Auto Insurance Policy
* `C1` - Commercial
* `CO` - Consolidated Omnibus Budget Reconciliation Act (COBRA)
* `CP` - Medicare Conditionally Primary
* `D` - Disability
* `DB` - Disability Benefits
* `EP` - Exclusive Provider Organization
* `FF` - Family or Friends
* `GP` - Group Policy
* `HM` - Health Maintenance Organization (HMO)
* `HN` - Health Maintenance Organization (HMO) - Medicare Risk
* `HS` - Special Low Income Medicare Beneficiary
* `IN` - Indemnity
* `IP` - Individual Policy
* `LC` - Long Term Care
* `LD` - Long Term Policy
* `LI` - Life Insurance
* `LT` - Litigation
* `MA` - Medicare Part A
* `MB` - Medicare Part B
* `MC` - Medicaid
* `MH` - Medigap Part A
* `MI` - Medigap Part B
* `MP` - Medicare Primary
* `OT` - Other | When this code is returned by Medicare or a Medicare Part D administrator, it indicates a type of insurance of Medicare Part D.
* `PE` - Property Insurance - Personal
* `PL` - Personal
* `PP` - Personal Payment (Cash - No Insurance)
* `PR` - Preferred Provider Organization (PPO)
* `PS` - Point of Service (POS)
* `QM` - Qualified Medicare Beneficiary
* `RP` - Property Insurance - Real
* `SP` - Supplemental Policy
* `TF` - Tax Equity Fiscal Responsibility Act (TEFRA)
* `WC` - Workers Compensation
* `WU` - Wrap Up Policy
## Military Service Rank Codes
Returned in the `subscriber.militaryServiceRankCode` and `dependents.militaryServiceRankCode` properties. These codes indicate the military service rank of the subscriber or dependent.
* `A1` - Admiral
* `A2` - Airman
* `A3` - Airman First Class
* `B1` - Basic Airman
* `B2` - Brigadier General
* `C1` - Captain
* `C2` - Chief Master Sergeant
* `C3` - Chief Petty Officer
* `C4` - Chief Warrant
* `C5` - Colonel
* `C6` - Commander
* `C7` - Commodore
* `C8` - Corporal
* `C9` - Corporal Specialist 4
* `E1` - Ensign
* `F1` - First Lieutenant
* `F2` - First Sergeant
* `F3` - First Sergeant-Master Sergeant
* `F4` - Fleet Admiral
* `G1` - General
* `G4` - Gunnery Sergeant
* `L1` - Lance Corporal
* `L2` - Lieutenant
* `L3` - Lieutenant Colonel
* `L4` - Lieutenant Commander
* `L5` - Lieutenant General
* `L6` - Lieutenant Junior Grade
* `M1` - Major
* `M2` - Major General
* `M3` - Master Chief Petty Officer
* `M4` - Master Gunnery Sergeant Major
* `M5` - Master Sergeant
* `M6` - Master Sergeant Specialist 8
* `P1` - Petty Officer First Class
* `P2` - Petty Officer Second Class
* `P3` - Petty Officer Third Class
* `P4` - Private
* `P5` - Private First Class
* `R1` - Rear Admiral
* `R2` - Recruit
* `S1` - Seaman
* `S2` - Seaman Apprentice
* `S3` - Seaman Recruit
* `S4` - Second Lieutenant
* `S5` - Senior Chief Petty Officer
* `S6` - Senior Master Sergeant
* `S7` - Sergeant
* `S8` - Sergeant First Class Specialist 7
* `S9` - Sergeant Major Specialist 9
* `SA` - Sergeant Specialist 5
* `SB` - Staff Sergeant
* `SC` - Staff Sergeant Specialist 6
* `T1` - Technical Sergeant
* `V1` - Vice Admiral
* `W1` - Warrant Officer
## Provider Codes
This code list is used in the request `provider.providerCode` property. It's also returned in the following response properties:
* `provider.providerCode`
* `benefitsInformation.benefitsRelatedEntities.providerInformation.providerCode`
These codes indicate the type of provider.
* `AD` - Admitting
* `AT` - Attending
* `BI` - Billing
* `CO` - Consulting
* `CV` - Covering
* `H` - Hospital
* `HH` - Home Health Care
* `LA` - Laboratory
* `OT` - Other Physician
* `P1` - Pharmacist
* `P2` - Pharmacy
* `PC` - Primary Care Physician
* `PE` - Performing
* `R` - Rural Health Clinic
* `RF` - Referring
* `SB` - Submitting
* `SK` - Skilled Nursing Facility
* `SU` - Supervising
## Quantity Qualifier Codes
Returned in the `benefitsInformation.quantityQualifierCode` property. These codes provide more information about the type of quantity.
* `8H` - Minimum
* `99` - Quantity Used
* `CA` - Covered - Actual
* `CE` - Covered - Estimated
* `D3` - Number of Co-insurance Days
* `DB` - Deductible Blood Units
* `DY` - Days
* `HS` - Hours
* `LA` - Life-time Reserve - Actual
* `LE` - Life-time Reserve - Estimated
* `M2` - Maximum
* `MN` - Month
* `P6` - Number of Services or Procedures
* `QA` - Quantity Approved
* `S7` - Age, High Value | Use this code when a benefit is based on a maximum age for the patient.
* `S8` - Age, Low Value | Use this code when a benefit is based on a minimum age for the patient.
* `VS` - Visits
* `YY` - Years
## Service Type Codes
Returned in the `benefitsInformation.serviceTypeCodes` array.
Visit [Service Type Codes](/healthcare/eligibility-active-coverage-benefits#service-type-codes) for a complete list. This list is specific to X12 version 005010, the mandated version for eligibility checks. It differs from the current [X12 Service Type Codes](https://x12.org/codes/service-type-codes) list, which applies to X12 versions later than 005010. Payers shouldn't send service type codes not explicitly listed in version 005010.
## Time Qualifier Codes
Returned in the `benefitsInformation.timeQualifierCode` and `benefitsInformation.benefitsServiceDelivery.timePeriodQualifierCode` properties. These codes provide more information about the time period to which the benefit applies.
* `6` - Hour
* `7` - Day
* `13` - 24 Hours
* `21` - Years
* `22` - Service Year
* `23` - Calendar Year
* `24` - Year to Date
* `25` - Contract
* `26` - Episode
* `27` - Visit
* `28` - Outlier
* `29` - Remaining
* `30` - Exceeded
* `31` - Not Exceeded
* `32` - Lifetime
* `33` - Lifetime Remaining
* `34` - Month
* `35` - Week
* `36` - Admission
# Eligibility Manager with Stedi Agent
Source: https://www.stedi.com/docs/healthcare/eligibility-manager
***
title: Eligibility Manager with Stedi Agent
sidebarTitle: "Eligibility Manager + Stedi Agent"
-------------------------------------------------
Eligibility Manager provides insight into your eligibility check pipeline and helps you identify, diagnose, and fix failed eligibility checks. For example, you can filter for all of the eligibility checks that failed during a payer outage and retry once the payer is back online.
In the app, you can:
* Review every eligibility check you submit through the app or Stedi APIs.
* Search and filter historical eligibility checks by status, Payer ID, date, and error code.
* Edit and retry failed eligibility checks and review the details of each attempt. With [Stedi Agent](#stedi-agent), you can resolve common recoverable errors automatically with the same best practices our Support team uses for troubleshooting.
* Use the Debug view to systematically troubleshoot failed eligibility checks until you receive a successful response from the payer.
## Example troubleshooting workflow
The following example shows how Eligibility Manager can help you track and resolve eligibility check failures:
You submit an eligibility check through Stedi's [Eligibility Check
API](/api-reference/healthcare/post-healthcare-eligibility) for Nick Smith.
Stedi sends it to the payer and creates a new eligibility search record in
the app containing the request details.
The payer returns an [AAA
error](/healthcare/eligibility-troubleshooting#payer-aaa-errors) code `75` -
Subscriber/Insured Not Found. Eligibility Manager shows that the status for
the new eligibility search is `Failed`.
You open the eligibility search, diagnose the error, correct the
subscriber's first name to "Nicholas", and submit the updated eligibility
check. Stedi stores the updated request as another entry in the existing
eligibility search.
The payer returns a successful response showing active insurance coverage
for Nicholas Smith. The status of the Eligibility Search changes to
`Active`, and you can view the request and response details for both
iterations of the eligibility check - the original failure and the
successful retry - within the same eligibility search record.
## Eligibility search
Eligibility Manager stores eligibility check requests in groups called eligibility searches.
When you submit an eligibility check through the app or API, Stedi creates a new eligibility search record. Every time you retry that eligibility check, Stedi stores the retry details within the existing eligibility search. This creates a clear timeline of troubleshooting efforts for failed requests.
### Create
You can create a new eligibility search through the app or Stedi APIs.
* **App:** Click **New search** and enter the eligibility check details into the interactive form.
* **API:** Use the [Eligibility Check API](/api-reference/healthcare/post-healthcare-eligibility) to submit an eligibility check programmatically.
Once you submit the eligibility check, Stedi creates a new eligibility search in the app.
#### External Patient ID
You can optionally add a **External Patient ID** to the request. This should be a unique identifier for the patient in your system. Adding this identifier helps you identify eligibility checks for the same patient over time.
### Filter
You can filter eligibility searches by the following criteria:
* **Error code:** By the [AAA code](/healthcare/eligibility-troubleshooting#payer-aaa-errors) returned by the payer. For example, `42` errors indicate a connectivity issue.
* **Payer:** By the Payer ID (62308) or business name (such as Cigna)
* **Status:** By Queued, Started, Failed, Inactive, and Active
* **Date:** A date range for when the initial eligibility check within an eligibility search was submitted. For example, a filter beginning on October 1st would only include eligibility searches with an initial submission on or after October 1st. It would *not* include an eligibility search with an initial submission on September 30th and a retry on October 1st.
* **Available actions:** Immediately find all eligibility searches that are eligible to edit and retry (errors in the request data) or retry without edits (error codes `42` and `80`, which indicate payer connectivity issues).
Results are sorted by the date of the original eligibility check within the eligibility search, with the most recent listed first.
### Statuses
The status of an eligibility search is determined by the most recent eligibility check in the record. For example, if the most recent iteration of a check failed, the status of the entire eligibility search is `Failed`, even if a previous version of the request succeeded.
An eligibility search can have one of the following statuses:
* **Queued:** Stedi placed the eligibility check in its internal queue and will send it to the payer when resources are available. This status is common when you schedule batch eligibility check refreshes through the API or perform large bulk retries that exceed your account's concurrency budget. You can typically expect the status to change to `Started` within a few seconds.
* **Started:** Stedi sent your eligibility check to the payer and is waiting for a response.
* **Failed:** The payer returned an error code in the response. Review the error code and retry the eligibility check.
* **Inactive:** The payer's response doesn't contain an active eligibility and benefit type.
* **Active:** The payer's response contains an active eligibility and benefit type (codes 1-5). Visit [Eligibility and benefit type codes](/healthcare/eligibility-active-coverage-benefits#benefit-type-codes) for a complete list.
## Retry failed eligibility checks
When an eligibility check fails, you can edit the request details and resubmit it until you get a successful response. You can either retry the entire eligibility search (the latest iteration of the eligibility check) or select a specific iteration to retry.
There are three ways to retry a failed eligibility check: using the [Stedi Agent](#stedi-agent), [manually resubmitting](#edit-and-retry) the request, or using [Debug view](#debug-view).
### Stedi Agent
The Stedi Agent uses our [Model Context Protocol (MCP) server](/healthcare/mcp-server) to troubleshoot and resolve common recoverable eligibility check errors automatically. To use it, you must be at least an [Operator](/accounts-and-billing#assigning-member-roles) role within your Stedi account.
To resolve a failure with the Stedi Agent:
1. Go to the [Eligibility searches page](https://portal.stedi.com/app/healthcare/eligibility).
2. Click **Resolve with Stedi Agent** next to an eligibility search. This is button is only available next to eligibility searches with common recoverable errors.
3. The Stedi Agent opens a side panel in [Debug view](#debug-view).
4. The Stedi Agent analyzes the eligibility request and works through best practice recovery strategies based on the error type. For example, if the payer returned an error code `75` (Subscriber/Insured Not Found), the agent may try different combinations of patient data or adjust the name format to find a match in the payer's system.
Each time the agent retries the eligibility check, it stores the new request in the same eligibility search record and it shows up in Debug view in real time. This allows you to see the history of attempts and the progression of the agent's troubleshooting efforts.
The agent only accesses data from the eligibility search it's working on. It can't access data from other searches, customers, or systems.
Please note:
* The Stedi Agent is available on all paid Stedi plans at no additional cost beyond those for related API calls.
* The agent is assistive. Outputs can be incorrect or incomplete. Verify all responses before taking any action based on them.
* You are responsible for any actions you instruct or authorize the AI service to take, including generating billable requests on your behalf.
### Edit and retry
To manually resubmit an eligibility check:
1. Go to the [Eligibility searches page](https://portal.stedi.com/app/healthcare/eligibility).
2. Click the eligibility search you want to troubleshoot to view its details.
3. Click **Actions > Edit and retry**.
4. Update the request details as needed, and click **Submit**.
You'll know the retry was successful when the [status of the eligibility search](#statuses) is either `Active` or `Inactive`. If the status of the eligibility search is still `Failed`, you may want to try resolving in [Debug view](#debug-view) or using the [Stedi Agent](#stedi-agent), if available.
### Debug view
Debug view is a workspace where you can systematically troubleshoot failed eligibility checks until you receive a successful response from the payer. For example, first you might try swapping the patient's nickname (Dave) for their full name (David) to see if that returns benefits information. In the next iteration, you might try submitting the request with a different service type code or dropping the date of birth.
Debug view shows all past iterations of the eligibility check and highlights the differences between each new version of the request. You can also draft and submit new requests directly from this page. This format helps you understand what you've already tried and quickly iterate on failed requests.
To troubleshoot eligibility checks in Debug view:
1. Go to the [Eligibility searches page](https://portal.stedi.com/app/healthcare/eligibility).
2. Click the eligibility search you want to troubleshoot to view its details.
3. Click **Actions > Debug** to enter Debug view.
4. Click **+ Add draft** to create a new draft request. Stedi pre-populates the draft with the details from the most recent eligibility check in the search.
5. Update the draft request as needed. Use the **Edit columns** list to show or hide specific fields in the request.
6. Click the green arrow when you're ready to submit the updated eligibility check draft.
Stedi runs the check and moves it to the list of **Past checks**. Stedi highlights the differences between it and other past checks so you can see a clear record of your troubleshooting efforts. You can repeat this process as many times as needed to get a successful response.
# Provider network status, authorizations, referrals
Source: https://www.stedi.com/docs/healthcare/eligibility-network-status-authorization-referrals
***
title: 'Provider network status, authorizations, referrals'
sidebarTitle: 'Provider network status, authorizations, referrals'
------------------------------------------------------------------
You have a few options for determining whether the requesting provider is in- or out-of-network for the patient. The most reliable method is contacting the payer or provider directly.
You can also use the `benefitsInformation` objects in the eligibility response to determine whether prior authorization or a referral is required for requested services.
## Is the provider in- or out-of-network?
Unfortunately, you can't reliably answer this question from a standard eligibility response.
Payers typically don't explicitly indicate whether the requesting provider is in- or out-of-network for the patient (though there are some [exceptions](#additional-network-status-details)). You also can't use the [`inPlanNetworkIndicatorCode` property](#in-plan-network-indicator) for this purpose. The `inPlanNetworkIndictorCode` indicates whether the specific benefit type applies to in- versus out-of-network, not the requesting provider.
The most reliable way to determine network status is to check directly with the payer or the provider. Note that payers may have different networks for different health plans, such as employer-sponsored plans versus Medicare Advantage, and these networks may have different contact paths.
### Payer FHIR APIs
Some payers have implemented the HL7 Da Vinci PDEX Plan Net (FHIR) API, which allows you to query directly for provider network status. Here are links to these APIs for a few large, commercial payers:
* [Aetna](https://developerportal.aetna.com/welcome)
* [Cigna](https://developer.cigna.com/docs/service-apis)
* [Humana](https://developers.humana.com/provider-directory-api/doc)
* [UnitedHealthcare](https://www.uhc.com/legal/interoperability-apis)
This is not an exhaustive list, and we provide these links for convenience and reference only. Stedi can't give any additional support on how to use third-party APIs.
### Additional network status details
Some payers do provide additional information about whether the requesting provider is in- or out-of-network. They may do this through either selective inclusion of benefits in the response or through freeform messages.
#### Selective inclusion of benefits
A small subset of payers selectively include portions of the eligibility response according to the provider’s network status. For example, some payers only return out-of-network benefits if the requesting provider is out-of-network. Likewise, if the provider is in-network, they only provide in-network benefits.
One example is Blue Cross and Blue Shield of New Mexico (BCBSNM). Their [270/271 Transaction Standard Companion Guide](https://www.bcbsnm.com/docs/provider/nm/nm_eligibility_benefits_270_271.pdf) states in section 5.3:
> "When local transactions are submitted, BCBSNM uses the provider type and/or provider specialty along with the providers contracting network status to determine the applicable benefits."
Stedi doesn't have a complete list of payers that selectively include or exclude benefits based on the provider's network status. The most reliable way to determine network status is to reach out to the provider or payer directly.
#### Freeform messages
While uncommon, some payers communicate information about the requesting provider's network status using freeform messages. For example, Cigna's [270/271 Companion Guide](https://www.cigna.com/static/www-cigna-com/docs/5010-270-271-companion-guide.pdf) states:
> "When the requestor's network participation status can be determined, Cigna will send a Message on the EB1\*30 Row that indicates either the Health Care Professional (or facility) is in or out of the customer's medical network."
In Stedi's eligibility response, these types of freeform messages are typically included in the `benefitsInformation.additionalInformation.description` property. For example:
* `PROVIDER IS OUT NETWORK FOR MEMBER`
* `BENEFITS RETURNED BASED ON NON-AFFILIATED PROVIDER STATUS`
This `description` property may also contain information about network tier levels, since some plans have more complex benefit structures with reduced patient responsibility for higher-tier providers.
**These freeform messages are not standardized across payers and may even differ across plans for the same payer.** Again, the most reliable way to determine network status is to reach out to the provider or payer directly.
### In Plan Network Indicator
The X12 EDI 271 eligibility response includes a data element called `EB12` (In Plan Network Indicator). Stedi represents this field as the `benefitsInformation.inPlanNetworkIndicatorCode` property in the eligibility benefits response.
Counterintuitively, **this value doesn't indicate whether the provider is in- or -out-of-network for the patient's health plan.**
Instead, the `InPlanNetworkIndicatorCode` specifies whether the specific benefit type applies to in- vs. out-of-network. Most payers include information about both the patient’s in- and out-of-network coverage and benefits in the response, regardless of the requesting provider's network status.
Payers can send the following `inPlanNetworkIndicatorCode` values:
* `Y` - Yes
* `N` - No
* `W` - Not Applicable | This indicates that the benefit applies to **both** in and out-of-network providers.
* `U` - Unknown | This indicates that it is unknown whether the benefits apply to in- or out-of-network providers.
The example `benefitsInformation` object below shows the patient's out-of-network deductible for the calendar year, which is $7,500 dollars. The `inPlanNetworkIndicatorCode` is `N`, indicating that the deductible is applicable to services performed by providers outside the patient's network.
{/* schema:BenefitsInformation */}
```json
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "7500",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
}
```
## Is prior authorization required?
Prior authorization (also called pre-authorization or pre-certification) is a requirement that the patient or their provider must get approval before a payer will cover specific services, procedures, medications, or devices. Without it, the payer may deny claims.
Payers use the `benefitsInformation.authOrCertIndicator` property to indicate whether prior authorization is required for the service type code in the eligibility check. It can have the following values:
* `Y` indicates that prior authorization is required.
* `N` indicates that prior authorization is not required.
* `U` indicates that the payer is unable to confirm whether or not prior authorization is required.
If you don't receive the `benefitsInformation.authOrCertIndicator` property in the response, you can assume that prior authorization is not required. Some payers may send additional notes about prior authorization rules in the `benefitsInformation.additionalInformation.description` property.
## Is a referral required?
A referral is a written or electronic authorization from a primary care physician (PCP) to see a specialist or receive certain services. Some health plans won't cover specialty care without a referral.
Payers aren't required to provide information about whether referrals are required for benefits, and we can't provide a definitive list of payers who do. When this information is included, you can find it in the `benefitsInformation.additionalInformation.description` property. You're more likely to receive referral information for members with HMO plans.
# Patient responsibility
Source: https://www.stedi.com/docs/healthcare/eligibility-patient-responsibility-benefits
***
title: 'Patient responsibility'
sidebarTitle: 'Patient responsibility'
--------------------------------------
Some benefits require the patient to pay a portion of the cost of care, also known as patient responsibility. For example, a patient may have a co-payment for in-office visits.
## Where can I find patient responsibility?
You can use `benefitsInformation` objects with `benefitsInformation.code` values `A`, `B`, `C`, `F`, `G`, and `Y` to determine the patient's financial responsibility for a given service type code (STC). These objects almost always contain either a `benefitAmount` or `benefitPercent` property that indicates the patient's responsibility.
The following example shows a sample response with three different types of patient responsibility:
* **Co-Payment:** The object with the `code` set to `B` shows that the patient's co-payment for pharmacy services is 10 dollars for in-network providers.
* **Deductible:** The object with the `code` set to `C` shows that the patient's deductible for general medical services is 1000 dollars per calendar year for in-network providers.
* **Co-Insurance:** The object with the `code` set to `A` shows that the patient's co-insurance for out-of-network for dental care is 0 percent for a comprehensive oral evaluation. The patient is allowed one visit every 6 months, and their last visit was on April 4, 2024.
{/* schema:BenefitsInformation:unwrapArray */}
```json
"benefitsInformation": [{
"code": "B",
"name": "Co-Payment",
"serviceTypeCodes": ["88"],
"serviceTypes": ["Pharmacy"],
"benefitAmount": "10",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes"
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "1000",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes"
},
{
"code": "A",
"name": "Co-Insurance",
"serviceTypeCodes": ["35"],
"serviceTypes": ["Dental Care"],
"benefitPercent": "0",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"compositeMedicalProcedureIdentifier": {
"productOrServiceIdQualifierCode": "AD",
"procedureCode": "D0150"
},
"benefitsDateInformation": {
"latestVisitOrConsultation": "20240404"
},
"benefitsServiceDelivery": [
{
"quantityQualifierCode": "VS",
"quantityQualifier": "Visits",
"quantity": "1",
"timePeriodQualifierCode": "34",
"timePeriodQualifier": "Month",
"numOfPeriods": "6"
}
]
}]
```
### Service history
Some benefits have frequency limits. For example, “one visit every 6 months” or “two cleanings per year.” Others depend on when the patient last received the service. If the patient has already reached the allowed frequency, the next visit may not be covered. In that case, they may owe the full amount.
To estimate patient cost for these types of benefits, you'll need to look at two additional properties in the `benefitsInformation` object:
* `benefitsDateInformation`: Shows when a service (like a cleaning or exam) was last performed.
* `benefitsServiceDelivery`: Indicates how often a service is allowed, such as once every 6 months or twice per year. Many payers don't populate this field and instead return this information as free text in additionalInformation.description.
These properties show up in responses for dental, vision, and Medicaid. They also apply to some medical services, like annual wellness visits or therapy sessions.
Some plans, especially dental, apply shared frequency limits across a group of procedures. For example, a plan might allow one X-ray series per year, regardless of the procedure code used later in the claim. If a claim has already been paid for one of the codes in the group, subsequent claims for others may be denied.
## Types of patient responsibility
The following types of benefits indicate patient financial responsibility for care. Note that payers may respond with zero in the `benefitAmount` or `benefitPercent` properties when the patient has no responsibility.
If a particular benefit category is not applicable to a plan, the payer will often send nothing for that category rather than explicitly sending a zero benefit. For example, if a health plan has 20% co-insurance for STC `98` but no co-payment, then typically none of the `benefitsInformation` array entries for that STC will have `benefitsInformation.code` = `B` (Co-Payment).
### Co-Insurance
Co-Insurance is indicated by `benefitsInformation.code` = `A` and always includes a value for the `benefitsInformation.benefitPercent` property.
Co-insurance represents the percentage of a benefit patients are responsible for covering themselves. For example, if a patient has met their annual deductible and their co-insurance is 20 percent, they would pay 20 dollars for a treatment that costs 100 dollars. The amount of co-insurance can differ depending on whether a provider is in-network with the health plan.
### Co-Payment
Co-Payment is indicated by `benefitsInformation.code` = `B` and always includes a value for the `benefitsInformation.benefitAmount` property.
Co-Payment represents a fixed dollar amount a patient must pay for a benefit. For example, a patient may have a 10 dollar co-payment for a physician office visit. The amount of co-payment can differ depending on whether the provider is considered in-network with the health plan.
### Cost Containment
Cost Containment is indicated by `benefitsInformation.code` = `J` and always includes a value for the `benefitsInformation.benefitAmount` property.
Cost Containment refers to rules that a health plan may have in place to control the cost of care. It's typically included in the eligibility response when the patient has Medicaid coverage and represents the total amount the patient will have to pay out of their own pocket before their benefits begin.
### Deductible
Deductible is indicated by `benefitsInformation.code` = `C` and always includes a value for the `benefitsInformation.benefitAmount` property.
A deductible represents the total amount the patient will have to pay out of their own pocket before their benefits begin. For example, if a patient's deductible is 1,000 dollars, they will have to pay 1,000 dollars for covered services before the health plan will start to pay. Then, the patient will typically pay part of the cost of services (such as co-payments) until they reach their out-of-pocket maximum.
Though behavior can vary by payer, the deductible `benefitsInformation` object is often included twice in the response for a given coverage level + service type + network status. One iteration contains a `timeQualifier` like `Calendar Year`, which indicates that the `benefitAmount` value is the patient's total annual deductible. In the second instance, the `timeQualifier` is often `Remaining`, which indicates that the `benefitAmount` value is the patient's *remaining* deductible amount (annual deductible minus what they've already spent for the calendar year).
#### No deductible for specific benefits
Some health plans list an annual deductible amount while offering a subset of benefits with a zero deductible. The most common case is preventive care benefits, which are usually required to be covered with no deductible or copay by the Affordable Care Act. For example, a High Deductible Health Plan (HDHP) may have a 3,000 dollar annual deductible, but cover an annual wellness visit at no cost.
For benefits with a zero deductible, the patient is not required to pay any amount out of pocket before coverage begins, regardless of whether they've met their annual deductible amount. Note that a zero deductible doesn't necessarily mean that the patient will pay nothing - their health plan may still require a co-payment or co-insurance for the benefit type.
Payers may indicate that a specific benefit has a zero deductible by including a `benefitsInformation` object with `benefitsInformation.code` = `C` and the `benefitsInformation.benefitAmount`set to `0`. Alternatively, they may simply send a message in the `benefitsInformation.additionalInformation.description` property indicating that the patient has no deductible.
#### No annual deductible
If the payer doesn't include a `benefitsInformation` object with `benefitsInformation.code` = `C`, you can generally assume that the patient has no annual deductible. This behavior is common with group HMO plans, which sometimes rely only on co-insurance or co-payment for cost control, but it can also occur with other types of health plans.
Medical payers are required to return deductible information for service type code `30` (Health Benefit Plan Coverage), so if the first eligibility response for another service type code doesn't include deductible information and you suspect that a deductible may still apply, then we recommend running another eligibility check for service type code `30`.
#### Example
In the following example:
* The first object shows that the patient has 500 dollars remaining to meet their annual deductible (`timeQualifier` = `Remaining`).
* The second object shows that the patient's annual deductible is 1,000 dollars (`timeQualifier` = `Calendar Year`).
{/* schema:BenefitsInformation:unwrapArray */}
```json
"benefitsInformation": [{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": [
"30"
],
"serviceTypes": [
"Health Benefit Plan Coverage"
],
"planCoverage": "GOLDLITE",
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "500",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"benefitsDateInformation": {
"benefit": "20240101-20241231"
}
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": [
"30"
],
"serviceTypes": [
"Health Benefit Plan Coverage"
],
"planCoverage": "GOLDLITE",
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "1000",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"benefitsDateInformation": {
"benefit": "20240101-20241231"
}
}]
```
### Limitations
Limitations are indicated by `benefitsInformation.code` = `F`. Dental and vision plans often use this benefit type to specify an annual maximum benefit amount.
The Affordable Care Act prevents most commercial health plans from imposing limits on annual or lifetime benefit amounts. However, this generally doesn't apply to government health plans and and some commercial health plans may be exempt. So we recommend checking for limitations for all plan types: medical, dental, and vision.
When present, limitations might include a value for the `benefitsInformation.benefitAmount` property that indicates the maximum benefit amount allocated to the patient. The `description` property is also often (but not always) set to a value like "ANNUAL MAXIMUM".
The following example shows a sample response from a dental payer. The patient has an annual maximum benefit for dental care of 2500 dollars.
{/* schema:BenefitsInformation */}
```json
{
"timeQualifier": "Calendar Year",
"inPlanNetworkIndicator": "Yes",
"timeQualifierCode": "23",
"benefitAmount": "2500",
"code": "F",
"coverageLevel": "Individual",
"inPlanNetworkIndicatorCode": "Y",
"serviceTypeCodes": [
"35"
],
"additionalInformation": [
{
"description": "ANNUAL MAXIMUM"
}
],
"serviceTypes": [
"Dental Care"
],
"name": "Limitations",
"coverageLevelCode": "IND"
}
```
### Out of Pocket (Stop Loss)
This benefits type doesn't apply to most dental plans.
Out of Pocket (Stop Loss) is indicated by `benefitsInformation.code` = `G` and always includes a value for the `benefitsInformation.benefitAmount` property.
Out of Pocket (Stop Loss) represents the maximum amount a patient can pay per year. Once the patient reaches this limit, the health plan will pay 100 percent of the allowed amount for covered services unless some other coverage limitation (code `F` [Limitations](#limitations)) applies. For example, if a health plan has a limit of 12 covered mental health visits per year, the patient may still be responsible for covering 100 percent of visits beyond that limit even if they have met their out-of-pocket maximum.
Most health plans are required to set an out-of-pocket maximum, but health plans with provider networks are allowed to have unlimited patient responsibility for out-of-network care. If there is no `benefitsInformation` object in the response that has `benefitsInformation.code` = `G`, the payer is indicating that the out-of-pocket maximum is unlimited.
### Spend Down
Spend Down is indicated by `benefitsInformation.code` = `Y` and always includes a value for the `benefitsInformation.benefitAmount` property.
Spend Down is a process that allows individuals with high medical expenses to qualify for Medicaid even if their income is above the Medicaid income limit. The Spend Down `benefitAmount` represents the total amount the patient will have to pay out of their own pocket before they can receive Medicaid benefits.
## When do payers return patient responsibility?
Not all service type codes (STCs) require payers to return patient responsibility information. For example, health plans are required to support inquiries for the following STCs, but aren't required to return patient responsibility information for them.
* `1` - Medical Care
* `30` - Health Plan Benefit Coverage
* `35` - Dental Care
* `88` - Pharmacy
* `AL` - Vision (Optometry)
* `MH` - Mental Health
However, health plans regulated under HIPAA **must** return any applicable patient co-insurance, co-payment, or deductible amounts for the following service type codes.
* `33` - Chiropractic
* `47` - Hospital
* `48` - Hospital Inpatient
* `50` - Hospital Outpatient
* `86` - Emergency Services
* `98` - Professional (Physician) Visit – Office
* `UC` - Urgent Care
These lists don't necessarily extend to dental or vision plans. Some payers may support returning patient responsibility information for additional STCs.
## No Surprises Act
The No Surprises Act is a federal law that protects patients from surprise medical bills — especially in emergency situations or when they unknowingly receive care from out-of-network providers. Under NSA, patients also have the right to a good faith estimate for non-emergency care if they're uninsured or self-pay.
The No Surprises Act bans surprise billing (also known as balance billing) in these situations:
* **Emergency Services:** Even if patients go to an out-of-network hospital or ER, they only have to pay in-network cost-sharing. This includes services at freestanding ERs and urgent care centers licensed to provide emergency care.
* **Non-Emergency Services at In-Network Facilities:** If patients go to an in-network hospital or surgery center, but an out-of-network provider (like an anesthesiologist or radiologist) treats them, they can't be charged more than their in-network rate.
* **Air Ambulance Services:** Patients are only responsible for their in-network rate.
### Does the NSA apply?
Payers don't typically note when the NSA applies to a patient's plan in the eligibility response. However, the NSA applies to most health plans, including fully insured and self-funded employer plans. It **doesn't** apply to:
* Ground ambulance services
* Medicare, Medicaid, TRICARE, or VA patients because these programs already have their own strong balance billing protections
* Some people with health care sharing ministries or short-term limited-duration plans
* Some unlicensed or unregulated providers
## Balance Billing Protection Act
The Balance Billing Protection Act (BBPA) is a Washington state law that protects patients from unexpected medical bills (also known as balance billing) when they receive care from out-of-network providers. It's similar to the No Surprises Act, but it applies specifically to Washington residents with state-regulated plans. It doesn't apply to self-funded employer plans unless they opt in.
The BBPA protects patients from balance billing in the following situations:
* Emergency services, even if patients are treated by an out-of-network provider or at an out-of-network facility.
* Non-emergency services at an in-network hospital or ambulatory surgical center when patients are unknowingly treated by an out-of-network provider (like an anesthesiologist or radiologist).
In these cases, the patient only pays their normal in-network cost-share (deductible, copay, coinsurance), and the provider must work out the rest with their insurer.
### Does the BBPA apply?
When the BBPA applies to a patient's health plan, payers are required to note this in `benefitsInformation` objects with a `benefitsInformation.code` of:
* `1` (Active Coverage)
* `2` (Active - Full Risk Capitation)
* `3` (Active - Services Capitated)
* `4` (Active - Services Capitated to Primary Care Physician)
* `5` (Active - Pending Investigation)
* `6` (Inactive)
* `7` (Inactive - Pending Eligibility Update)
* `8` (Inactive - Pending Investigation)
In these cases, you will see one of the following messages in the `benefitsInformation.additionalInformation.description` property:
> Services provided to this patient are subject to the Balance Billing Protection Act. Please see RCW 48.49.020 for details.
> Services provided to this patient are subject to the No Surprises Act. Please see RCW 48.49.020 for details.
The following example shows a `benefitsInformation` object with the BBPA message included in the `additionalInformation` array.
{/* schema:BenefitsInformation */}
```json
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"30"
],
"serviceTypes": [
"Health Benefit Plan Coverage"
],
"planCoverage": "Open Access Plus",
"additionalInformation": [
{
"description": "Complete Care Management",
"description": "Services provided to this patient are subject to the Balance Billing Protection Act. Please see RCW 48.49.020 for details."
}
]
}
```
# STCs and procedure codes
Source: https://www.stedi.com/docs/healthcare/eligibility-stc-procedure-codes
***
title: STCs and procedure codes
sidebarTitle: "STCs and procedure codes"
----------------------------------------
You're likely running an eligibility check to determine the patient's coverage and financial responsibility for particular medical or dental services, such as chiropractic or hospice care.
You can retrieve specific types of benefits information from the payer by including either a service type code (STC) or a procedure code and qualifier in your request.
However, it's not always clear which STC or procedure code to use for best results. This page explains how to choose the right STC or procedure code for your eligibility check, how to test whether a payer supports a specific STC, and how to map procedure codes to STCs when necessary.
## Should I use STCs or procedure codes?
It depends on the type of benefits information you want to retrieve.
### Medical benefits
You'll almost always need to submit an STC because most medical payers don't support procedure codes (CPT/HCPCS/CDT). Refer to our guidance for [choosing STCs](#choose-the-right-stc).
### Dental benefits
Many (but not all) dental payers support procedure codes. However, we recommend:
1. First try STC `35` - especially if you need information about general dental benefits. Many payers only return comprehensive dental-specific benefits for STC `35`.
2. Try the relevant CDT code if you still need more benefits information for a specific service.
3. If the CDT code still doesn't return what you need, try the STC mapped to that CDT code. Refer to our list of [common mappings](/healthcare/eligibility-stc-procedure-codes#dental) for dental benefits.
## Choose the right STC
A Service Type Code (STC) is a two-character code that groups similar healthcare services into standard categories, such as `47` (Hospital) and `UC` (Urgent Care). STC support varies by payer:
* Not all payers support all STCs.
* Some payers only respond to the first STC you send and ignore the rest.
* Some payers completely ignore the STCs in the request and always return a default response for STC `30` (Health Benefit Plan Coverage).
* Some payers don't support multiple STCs in a single request.
* Some payers do support multiple STCs, but only a limited number per request.
When choosing an STC, we recommend:
* Send the most specific STC you can for the services you're targeting. You should [test the STCs](#test-payer-stc-support) that seem most appropriate to determine which ones yield the most benefits information. Refer to our list of [STCs for common services](#stcs-for-common-services).
* If no specific STC seems appropriate or if the payer doesn't support it, fall back to a [general benefit check](#general-benefit-checks).
* Include only one STC per request, unless you've tested the payer and confirmed they support multiple STCs in a single request *and* that the response contains better benefits information when you include more than one.
If after testing, no STC produces the benefits information you need, you may need to call the payer or visit the payer portal.
### General benefit checks
Use STC `30` for general medical benefits or `35` for general dental benefits. These STCs are supported by all payers and are a good fall back when a payer doesn't support a more specific STC.
When you send STC `30` in an eligibility check, all payers must return benefits information for the following STCs when the patient's plan covers them:
* `1` (Medical Care)
* `33` (Chiropractic)
* `47` (Hospital)
* `86` (Emergency Services)
* `88` (Pharmacy)
* `98` (Professional Physician Visit - Office)
* `AL` (Vision - Optometry)
* `MH` (Mental Health)
* `UC` (Urgent Care)
[CAQH CORE-certified payers](#required-stcs-for-core-certified-payers) are required to support a broader set of STCs.
### STCs for common services
Try the following STCs in the order shown - from the most specific to more general alternatives. We recommend sending only one STC at a time, unless you've [tested the payer](#test-payer-stc-support) and confirmed they support multiple in a single request.
We've also included the mapping to specific procedure codes where possible, to make it easier to determine the right STC for your use case. Ranges of applicable codes are represented as `rangeStart - rangeEnd`.
#### Medical
| Procedure codes | Type of care | STCs to try |
| ---------------------------------------------------------------------------------------- | -------------------------------------------- | ---------------------------------------------------- |
| `97151 - 97157` | ABA Therapy | `BD`, `MH` |
| `97810`, `97811 - 97814` | Acupuncture | `64`, `1` |
| `96401 - 96549` | Chemotherapy | `ON`, `82`, `92` |
| `96493` | Chemotherapy, IV push | `82`, `92` |
| `96494` | Chemotherapy, additional infusion | `82`, `92` |
| `99490`, `99439`, `99491`, `99437`, `99487` | Chronic Care Management (CCM) services | `A4`, `MH`, `98`, `1` |
| too many to list | Dermatology | `3`, `98` |
| `E1399` | Durable Medical Equipment | `DM`, `11`, `12`, `18` |
| `96375` | IV push | `92` |
| `96360`, `96365`, `96366` | IV Therapy/Infusion | `92`, `98` |
| too many to list | Maternity (professional) | `BT`, `BU`, `BV`, `69` |
| `97802` | Medical nutrition therapy | `98`, `MH`, `1` |
| `97803` | Medical nutrition follow-up | `98`, `MH`, `1` |
| too many to list | Mental health | `MH`, `96`, `98`, `A4`, `BD`, `CF` |
| `95700 - 96020` | Neurology | `98` |
| `99460`, `99463` | Newborn/facility | `65`, `BI` |
| `97165 - 97168` and `97110`, `97530`, `97112`, `97140`, `97535`, `97116`, `97129` | Occupational therapy | `AD`, `98` |
| `97110`, `97112`, `97116`, `97350`, and several others | Physical therapy | `PT`, `AE` |
| too many to list | Podiatry | `93`, `98` |
| too many to list | Primary care | `96`, `98`, `A4`, `A3`, `99`, `A0`, `A1`, `A2`, `98` |
| `99214` | Psychiatry visits | `A4`, `MH` |
| `96130` | Psychological testing evaluation | `A4`, `MH` |
| `90832`, `90834`, `90837`, `90833`, `90836`, `90838`, `90839`, `90846`, `90847`, `90849` | Psychotherapy | `96`, `98`, `A4`, `BD`, `CF` |
| too many to list | Rehabilitation | `A9`, `AA`, `AB`, `AC` |
| `98975`, `98976`, `98977`, `98980`, `98981` | Remote Therapeutic Monitoring (RTM) services | `A4`, `98`, `MH`, `92`, `DM`, `1` |
| `99304-99318` | Skilled Nursing | `AG`, `AH` |
| `92507`, `92508`, `92521`, `92522`, `92523`, `92526`, `92607`, `92609`, `92605`, `92618` | Speech Therapy | `AF`, `98` |
| `90791`, `90832`, `90834`, `90837`, `90853`, `99408`, `99409`, and `H0017-H0019` | Substance Abuse/Addiction | `AI`, `AJ`, `AK`, `MH` |
| `99202-99215`, `99421-99423`, `99441-99443`, `G2010` and `G2012` | Telehealth | `9`, `98` |
| `90867` | Transcranial magnetic stimulation | `A4`, `MH` |
#### Dental
| Procedure | Type of care | STCs to try |
| --------- | ------------------------------------- | ----------- |
| `D4210` | Gingivectomy or gingivoplasty | `25` |
| `D4381` | Local delivery of antimicrobial agent | `25` |
| `D5110` | Complete maxillary (upper) denture | `39` |
### Full STC list
You can include the following STCs in an eligibility check. Not all payers support all STCs, so you should always [test each payer](#test-payer-stc-support) to ensure they support the STCs you plan to use.
* The word physician in service type codes refers to any healthcare provider, including physician assistants, nurse practitioners, and other types of healthcare professionals.
* **Don't send STCs that aren't in this list.** This list is specific to X12 version 005010, the mandated version for eligibility checks. It's different from the [X12 Service Type Codes](https://x12.org/codes/service-type-codes) list, which applies to X12 versions later than 005010. Payers shouldn't accept or send STCs not explicitly listed in version 005010.
- `1` Medical Care
- `2` Surgical
- `3` Consultation
- `4` Diagnostic X-Ray
- `5` Diagnostic Lab
- `6` Radiation Therapy
- `7` Anesthesia
- `8` Surgical Assistance
- `9` Other Medical
- `10` Blood Charges
- `11` Used Durable Medical Equipment
- `12` Durable Medical Equipment Purchase
- `13` Ambulatory Service Center Facility
- `14` Renal Supplies in the Home
- `15` Alternate Method Dialysis
- `16` Chronic Renal Disease (CRD) Equipment
- `17` Pre-Admission Testing
- `18` Durable Medical Equipment Rental
- `19` Pneumonia Vaccine
- `20` Second Surgical Opinion
- `21` Third Surgical Opinion
- `22` Social Work
- `23` Diagnostic Dental
- `24` Periodontics
- `25` Restorative
- `26` Endodontics
- `27` Maxillofacial Prosthetics
- `28` Adjunctive Dental Services
- `30` Health Benefit Plan Coverage - **supported by all payers**
- `32` Plan Waiting Period
- `33` Chiropractic
- `34` Chiropractic Office Visits
- `35` Dental Care
- `36` Dental Crowns
- `37` Dental Accident
- `38` Orthodontics
- `39` Prosthodontics
- `40` Oral Surgery
- `41` Routine (Preventive) Dental
- `42` Home Health Care
- `43` Home Health Prescriptions
- `44` Home Health Visits
- `45` Hospice
- `46` Respite Care
- `47` Hospital
- `48` Hospital - Inpatient
- `49` Hospital - Room and Board
- `50` Hospital - Outpatient
- `51` Hospital - Emergency Accident
- `52` Hospital - Emergency Medical
- `53` Hospital - Ambulatory Surgical
- `54` Long Term Care
- `55` Major Medical
- `56` Medically Related Transportation
- `57` Air Transportation
- `58` Cabulance
- `59` Licensed Ambulance
- `60` General Benefits
- `61` In-vitro Fertilization
- `62` MRI/CAT Scan
- `63` Donor Procedures
- `64` Acupuncture
- `65` Newborn Care
- `66` Pathology
- `67` Smoking Cessation
- `68` Well Baby Care
- `69` Maternity
- `70` Transplants
- `71` Audiology Exam
- `72` Inhalation Therapy
- `73` Diagnostic Medical
- `74` Private Duty Nursing
- `75` Prosthetic Device
- `76` Dialysis
- `77` Otological Exam
- `78` Chemotherapy
- `79` Allergy Testing
- `80` Immunizations
- `81` Routine Physical
- `82` Family Planning
- `83` Infertility
- `84` Abortion
- `85` AIDS
- `86` Emergency Services
- `87` Cancer
- `88` Pharmacy
- `89` Free Standing Prescription Drug
- `90` Mail Order Prescription Drug
- `91` Brand Name Prescription Drug
- `92` Generic Prescription Drug
- `93` Podiatry
- `94` Podiatry - Office Visits
- `95` Podiatry - Nursing Home Visits
- `96` Professional (Physician)
- `97` Anesthesiologist
- `98` Professional (Physician) Visit - Office
- `99` Professional (Physician) Visit - Inpatient
- `A0` Professional (Physician) Visit - Outpatient
- `A1` Professional (Physician) Visit - Nursing Home
- `A2` Professional (Physician) Visit - Skilled Nursing Facility
- `A3` Professional (Physician) Visit - Home
- `A4` Psychiatric - `A5` Psychiatric - Room and Board
- `A6` Psychotherapy
- `A7` Psychiatric - Inpatient
- `A8` Psychiatric - Outpatient
- `A9` Rehabilitation
- `AA` Rehabilitation - Room and Board
- `AB` Rehabilitation - Inpatient
- `AC` Rehabilitation - Outpatient
- `AD` Occupational Therapy
- `AE` Physical Medicine
- `AF` Speech Therapy
- `AG` Skilled Nursing Care
- `AH` Skilled Nursing Care - Room and Board
- `AI` Substance Abuse
- `AJ` Alcoholism
- `AK` Drug Addiction
- `AL` Vision (Optometry)
- `AM` Frames
- `AN` Routine Exam - Use for Routine Vision Exam only
- `AO` Lenses
- `AQ` Nonmedically Necessary Physical
- `AR` Experimental Drug Therapy
- `B1` Burn Care
- `B2` Brand Name Prescription Drug - Formulary
- `B3` Brand Name Prescription Drug - Non-Formulary
- `BA` Independent Medical Evaluation
- `BB` Partial Hospitalization (Psychiatric)
- `BC` Day Care (Psychiatric)
- `BD` Cognitive Therapy
- `BE` Massage Therapy
- `BF` Pulmonary Rehabilitation
- `BG` Cardiac Rehabilitation
- `BH` Pediatric
- `BI` Nursery
- `BJ` Skin
- `BK` Orthopedic
- `BL` Cardiac
- `BM` Lymphatic
- `BN` Gastrointestinal
- `BP` Endocrine
- `BQ` Neurology
- `BR` Eye
- `BS` Invasive Procedures
- `BT` Gynecological
- `BU` Obstetrical
- `BV` Obstetrical/Gynecological
- `BW` Mail Order Prescription Drug - Brand Name
- `BX` Mail Order Prescription Drug - Generic
- `BY` Physician Visit - Office: Sick
- `BZ` Physician Visit - Office: Well
- `C1` Coronary Care
- `CA` Private Duty Nursing - Inpatient
- `CB` Private Duty Nursing - Home
- `CC` Surgical Benefits - Professional (Physician)
- `CD` Surgical Benefits - Facility
- `CE` Mental Health Provider - Inpatient
- `CF` Mental Health Provider - Outpatient
- `CG` Mental Health Facility - Inpatient
- `CH` Mental Health Facility - Outpatient
- `CI` Substance Abuse Facility - Inpatient
- `CJ` Substance Abuse Facility - Outpatient
- `CK` Screening X-ray - `CL` Screening Laboratory
- `CM` Mammogram, High Risk Patient
- `CN` Mammogram, Low Risk Patient
- `CO` Flu Vaccination
- `CP` Eyewear and Eyewear Accessories
- `CQ` Case Management
- `DG` Dermatology
- `DM` Durable Medical Equipment
- `DS` Diabetic Supplies
- `GF` Generic Prescription Drug - Formulary
- `GN` Generic Prescription Drug - Non-Formulary
- `GY` Allergy
- `IC` Intensive Care
- `MH` Mental Health
- `NI` Neonatal Intensive Care
- `ON` Oncology
- `PT` Physical Therapy
- `PU` Pulmonary
- `RN` Renal
- `RT` Residential Psychiatric Treatment
- `TC` Transitional Care
- `TN` Transitional Nursery Care
- `UC` Urgent Care
### Test payer STC support
We recommend testing each payer to determine which STC(s) they support and which STC(s) return the most benefits information for the services you care about.
To test whether a payer supports a specific STC:
1. Send a baseline request with just STC `30` for general medical benefits or `35` for general dental benefits.
2. Send a request with the specific STC that best matches the benefit type you want to check. For example, to check mental health benefits, you might send a request with STC `MH` (Mental Health). Use our list of [STCs for common services](#stcs-for-common-services) as a starting point.
3. Compare the baseline response with the response to the specific STC. If they're different, the payer likely supports the specific STC.
You may also want to test whether the payer supports multiple STCs in a single request:
1. Send a baseline request with just STC `30` for general medical benefits or `35` for general dental benefits.
2. Send a request with multiple STCs matching the benefit types you want to check.
3. Compare the responses. If they change based on the number of STCs, the payer likely supports multiple STCs in a single request. If not, the payer may be ignoring or only partially supporting STCs - for example, they may only be returning information for the first STC.
We recommend scripting your requests to speed up the testing process. Specifically, you should loop through candidate STCs and compare the responses against the baseline STC `30` or `35` response for the same patient. You can also save the `benefitsInformation` array for each STC and diff them. This approach helps you more easily identify changes between test requests.
## Map procedure codes to STCs
It can be hard to map procedure codes to the right STC. For example, if a provider offers medical nutrition therapy and bills using CPT code 97802, should they use service type code `1` - Medical Care, `3` - Consultation, `MH` - Mental Health, or another option?
Unfortunately, there's no standardized mapping between procedure codes and STCs. In fact, payers themselves often don't have an explicit mapping for their own health plans. Their eligibility check systems aren't necessarily directly integrated with their claims processing systems, so when you ask them which STC to use, they may not always be able to provide a good answer.
Review our list of [STCs for common services](#stcs-for-common-services), which contains mappings to the associated procedure codes. If you don't find the procedure code you're looking for, use the following approaches to determine the best STC for your use case:
* Review the payers' documentation for eligibility checks. Some payers provide a list of STCs they support and their mappings to procedure codes.
* If you can't find the information in the payer's documentation, contact the payer directly or reach out to [Stedi support](https://www.stedi.com/contact), and we'll contact the payer for you.
* For dental payers that don't support specific CDT codes, you can use either of these sources to map CDT codes to service type codes. You can either purchase a copy of these documents or contact Stedi support for recommendations about specific mappings:
* NDEDIC's [Companion to ASC X12 270/271](https://ndedic.org/Sys/Store/Products/1016)
* Table 6 in the American Dental Association's [Technical Report No. 1102](https://engage.ada.org/p/eg/ada-technical-report-no-1102-electronic-dental-benefits-eligibility-verification-e-book-1390?itm_source=pp-1316\&itm_component=p-related).
* If none of the above methods work, you can ask a medical coder with [AAPC certification](https://www.aapc.com/certifications) for guidance. Their familiarity with billable codes will help them make good recommendations about service type code mappings.
Once you determine the right STC code(s), we recommend maintaining an internal document that contains the mappings for the health plans you most frequently bill.
## Required STCs for CORE-Certified payers
CAQH CORE creates operating rules and frameworks that improve interoperability in healthcare data exchange. CORE requires certified payers to support a broader set of STC codes than those mandated for [general benefits inquiries](#general-benefit-checks).
If the plan covers the service, certified payers must return benefit information for the following STCs. Visit CAQH CORE's website for a complete list of [CORE-Certified Health Plans](https://www.caqh.org/core/core-certified-organizations-pending-and-current).
* `4` Diagnostic X-Ray
* `5` Diagnostic Lab
* `6` Radiation Therapy
* `7` Anesthesia
* `8` Surgical Assistance
* `12` DME Purchase
* `13` Ambulatory Surgery Facility
* `18` DME Rental
* `20` Second Surgical Opinion
* `30` Health Benefit Plan Coverage
* `33` Chiropractic
* `62` MRI/CAT Scan
* `65` Newborn Care
* `68` Well Baby Care
* `78` Chemotherapy
* `80` Immunizations
* `81` Routine Physical
* `82` Family Planning
* `86` Emergency Services
* `93` Podiatry
* `98` Physician Visit - Office
* `99` Physician Visit - Inpatient
* `A0` Physician Visit - Outpatient
* `A3` Physician Visit - Home
* `AD` Occupational Therapy
* `AE` Physical Medicine
* `AF` Speech Therapy
* `AG` Skilled Nursing Care
* `BG` Cardiac Rehabilitation
* `BH` Pediatric
## STCs in the eligibility response
To determine whether the payer is returning the benefits information you need, you must check the [`benefitsInformation` array](/api-reference/healthcare/post-healthcare-eligibility#response.benefitsInformation). Each object in this array contains a `serviceTypeCodes` property that lists the applicable STCs.
The payer may send benefits information for additional STCs you didn't request - this is expected. It can also mean that the payer is ignoring the STC you sent, which is why we recommend [testing payers](#test-payer-stc-support) to determine their support for specific STCs.
The following example shows a `benefitsInformation` object that specifies a patient's co-payment ($20) for psychiatric, psychotherapy, and social work in-office visits.
```json
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"industryCode": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"industryCode": "Office"
}
]
}
```
You should review the [STC list](/healthcare/eligibility-stc-procedure-codes#full-stc-list) to determine which STCs are relevant to the benefits you're interested in and check for all of them in the response. This is helpful because the payer may return relevant benefits under a different STC than the one you submitted. For example, mental health benefits are typically returned with STC `MH` (Mental Health), but some payers may use other STCs, such as `BH` (Behavioral Health), `A4` (Psychiatric) or `SA` (Substance Abuse) for related services.
You should also check all `benefitsInformation` objects with relevant `serviceTypeCodes` values because the same STC is typically repeated across multiple `benefitsInformation` objects in the response.
* Each object communicates a different aspect of benefits, such as coverage status, co-pays, or deductibles.
* Payers also use multiple objects to describe different subsets of services within an STC. For example, the `MH` STC might have one entry for standard therapy and another that notes coverage for other treatments. Descriptions typically appear in entries with code: `"1" (Active Coverage)` or code: `"D" (Benefit Description)`, but they can appear in other entries as well.
To learn more about interpreting the eligibility response, visit [Determine patient benefits](/healthcare/eligibility-active-coverage-benefits).
# Eligibility troubleshooting
Source: https://www.stedi.com/docs/healthcare/eligibility-troubleshooting
***
title: Eligibility troubleshooting
sidebarTitle: "Troubleshooting"
-------------------------------
A list of potential errors and possible resolutions when submitting 270/271 eligibility checks.
## Payer unable to find patient
Sometimes, a payer can't return benefits information for a patient even when the patient exists in their system. This problem can occur for a couple reasons.
### Multiple matching records
Payers can have multiple records of patients with the same name and date of birth. The payer cannot return benefits information unless they are able to identify a unique match within their system.
To avoid this issue, we recommend:
* Include all of the demographic information available for a patient.
* Include the patient's member ID, if available.
### Information discrepancies
There can be discrepancies between the information the provider has collected from the patient and the record the payer has in their system. These discrepancies can lead to issues returning a patient, even though a match exists. Some examples include differences in spelling the patient's name, using a nickname instead of the full name ("Nick" vs. "Nicolas"), and accidentally transposing numbers in the date of birth.
If a request fails to return the expected member in the response, we recommend progressively sending additional eligibility check requests with fewer patient identity and demographic data elements, or different combinations of those. This allows you to identify and handle cases where there are data errors or discrepancies between payer and provider data.
### Name mismatches
If the payer fails to find a matching plan member due to a name mismatch, the `errors` array in the response typically has the `code` set to one of the following values:
* `65`: Invalid/Missing Patient Name
* `67`: Patient Not Found
* `73`: Invalid/Missing Subscriber/Insured Name
* `75`: Subscriber/Insured Not Found
These error codes are set by the payer, not by Stedi, so it's possible that other error codes could be returned.
Resolving the error may require trying different name variations until the check is successful.
* Replace any nickname or shortened name with the full legal name, for example "Robert" instead of "Bob".
* Replace any non-English or accented characters (letters with diacritical marks) such as "Ñ" or "é" with the closest equivalent within the character restrictions. Stedi automatically replaces most such characters with the usual closest equivalent but this might not match the payer's record. For example, the character "Đ" could be transliterated to "D" or "J" depending on the romanization system used.
* For compound names try using only one or the other part. You can also try try removing the separator, or changing the separator from hyphen to space, or vice versa. Some payers may ignore special or separator characters when performing name searches.
* If the patient has recently changed their name, for example due to marriage, then the name stated by the patient or printed on their ID card might not match the payer's record. Try both the current and previous name.
## Retry strategy
Implementing the right retry strategy for eligibility check failures saves a lot of time and money.
At a minimum, we **strongly recommend** automatically retrying every request that fails due to payer connectivity issues. Automatic retries resolve a significant portion of these types of failures without manual intervention.
### Payer connectivity issues
We recommend implementing automatic retries for all of the following [`AAA` error](/healthcare/eligibility-troubleshooting#payer-aaa-errors) cases. These scenarios indicate temporary payer downtime, throttling, or intermittent connectivity issues:
* `42` (Unable to Respond at Current Time)
* `42` (Unable to Respond at Current Time) and `79` (Invalid Participant Identification)
* `80` (No Response received - Transaction Terminated)
Our recommended retry strategy depends on your eligibility check workflow.
#### Real-time eligibility checks
For real-time eligibility checks that require a response within a few minutes, we recommend:
* Retry immediately and continue retrying for up to 2 minutes.
* The recommended retry window is based on what's acceptable in real-time human workflows. For example, a patient checking in for an appointment at their doctor's office.
* If the request is still unsuccessful, fail gracefully and escalate as needed.
#### Scheduled eligibility checks
You may want to run scheduled or background eligibility checks to perform periodic refreshes for a patient population or when checking eligibility for upcoming appointments.
If you're using the [Batch Eligibility Check](/api-reference/healthcare/post-healthcare-batch-eligibility) endpoint (recommended), Stedi automatically retries checks that fail due to payer connectivity issues for up to 8 hours.
If you're submitting real-time checks that can tolerate longer wait times, we recommend:
* Wait 1 minute to perform the first retry.
* Then, exponentially increase the wait between subsequent retries to up to 30 minutes between attempts.
* We recommend retrying for at least 8 hours, but the retry window should be based on your business workflows.
### Other common error cases
You should also consider the following common error cases when implementing retries:
| AAA error | HTTP status | Reason | Retry Strategy |
| --------- | ----------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| - | `429` | You exceeded your Stedi concurrency limit. | Retry immediately. Monitor your open concurrent requests and immediately replace any finished requests under your Stedi account limit. |
| `79` | `200` | Stedi successfully sent your request to the payer, but the payer rejected it. | First, retry as soon as possible with a different member and a different [NPI](/healthcare/national-provider-identifier). This helps determine whether the issue is with the original request or there is a broader issue with the payer. If you determine the issue is with the payer, follow our guidance for [payer connectivity issues](#payer-connectivity-issues). |
| `79` | `400` | Either Stedi doesn't recognize the payer ID you provided, or the payer is not configured for eligibility checks. | **Don't automatically retry.** Fix the payer ID or contact Stedi support to resolve. |
## Errors
You may encounter the following types of errors when submitting eligibility requests.
### Stedi payer errors
Stedi returns errors when it encounters issues with the payer ID you provided.
\| Error message | Possible causes and resolutions |
\| ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
\| `Payer is not configured for {transaction type}. Please contact Stedi support to resolve.` | Stedi does not yet support this transaction type for this payer, or there is a mis-mapping of payer IDs. Contact us with the name of the payer, and we'll investigate the issue. |
\| `Payer connection does not support {transaction type}. Please contact Stedi support to discuss connectivity options.` | Stedi has a connection to this payer, but it doesn't currently support this functionality (real-time eligibility or claim submission). Contact us for a timeline on enabling it. |
\| `Payer is not configured. Please check our published payer list or contact Stedi support to resolve.` | Stedi doesn't recognize the payer ID you provided. Double-check the payer ID in the [Stedi Payer Network](https://www.stedi.com/healthcare/network), or contact us with the name of the payer, and we will help you determine the correct payer ID. |
\| `Payer is not supported. Please contact Stedi support to discuss connectivity options.` | Stedi doesn't yet have connectivity to this payer. We're likely already working on it - contact us for details about the connectivity timeline. |
The following error resulted from an unrecognized payer ID:
{/* schema:EligibilityCheckResponseContent */}
```json
{
"controlNumber": "123456789",
"tradingPartnerServiceId": "TEST2",
"errors": [
{
"code": "79",
"description": "Invalid Participant Identification",
"followupAction": "Please Correct and Resubmit",
"location": "2100A",
"possibleResolutions": "Payer TEST2 is not configured. Please check our published payer list or contact Stedi support to resolve."
}
],
"status": "ERROR"
}
```
### Validation errors
Stedi validates the structure of your eligibility request and will not submit your request to the payer if it is missing required fields or if the data is not formatted correctly. The following Stedi validation error resulted from a missing `provider` object:
{/* schema:EligibilityCheckResponseContent */}
```json
{
"controlNumber": "123456789",
"tradingPartnerServiceId": "CIGNA",
"errors": [
{
"code": "33",
"description": "Input Errors",
"followupAction": "Please Correct and Resubmit",
"possibleResolutions": "Missing required field: provider"
}
],
"status": "ERROR"
}
```
### Payer AAA errors
When a payer rejects your eligibility check, the 271 response contains one or more [`AAA` Request Validation segments](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-response-x279a1/01GS66YHZPB37ABF34DBPSR213#properties.detail.properties.information_source_level_HL_loop.items.properties.request_validation_AAA) that specify the reasons for the rejection and any recommended follow-up actions. Stedi includes this information in the `aaaErrors` object in the response JSON.
Common causes for AAA errors include:
* Missing or incorrect information for the subscriber, dependent, provider, or payer. In this case, you should correct any errors before resubmitting.
* Issues with payer [enrollment](/healthcare/credentialing-and-enrollment). Many of these issues require that the provider contact the payer directly to resolve, due to PHI/HIPAA guidelines.
* The payer's system is down or experiencing issues. In this case, the payer may not have actually validated the data in your request. If you receive these types of errors, you should wait a few minutes and resend the request again.
Each error contains a `followupAction`:
* Please Correct and Resubmit
* Resubmission Not Allowed | Note that this code doesn't mean you should never resubmit the request. Intermediary clearinghouses may send this code when they have temporarily lost connection to the payer, so this code indicates that you should wait at least a few minutes before retrying instead of retrying immediately.
* Resubmission Allowed
* Do Not Resubmit; Inquiry Initiated to a Third Party | This code is uncommon
* Please Resubmit Original Transaction
* Please Wait 30 Days and Resubmit | This code is uncommon
* Please Wait 10 Days and Resubmit | This code is uncommon
* Do not resubmit; We Will Hold Your Request and Respond Again Shortly | This code is uncommon
AAA errors can be present at multiple different levels in the response, depending on the type. The following example shows an error at the subscriber level (`subscriber.aaaErrors`):
{/* schema:EligibilityCheckResponseContent */}
```json
{
"subscriber": {
"memberId": "123456789",
"firstName": "JANE",
"lastName": "DOE",
"entityIdentifier": "Insured or Subscriber",
"entityType": "Person",
"dateOfBirth": "19001103",
"aaaErrors": [
{
"field": "AAA",
"code": "75",
"description": "Subscriber/Insured Not Found",
"followupAction": "Please Correct and Resubmit",
"location": "Loop 2100C",
"possibleResolutions": "- Subscriber was not found."
}
]
}
}
```
However, all errors at the `payer`, `provider`, `subscriber`, and `dependents` levels are also reported in the top-level `errors` array in the eligibility check response.
Visit [Eligibility mock requests](/api-reference/healthcare/mock-requests-eligibility-checks)
to retrieve more examples of common AAA errors in eligibility responses.
To help with troubleshooting, we include additional strings containing possible causes and resolutions for each `AAA` error. We periodically update this guidance, so these strings may change at any time and may differ between eligibility responses. **Don't build programmatic logic that depends on matching these strings exactly.**
#### Payer
You may receive the following types of errors at the `payer` level.
| Code | Description | Possible causes and resolutions |
| ---- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `04` | Authorized Quantity Exceeded | You included too many patients in the request - you can only request benefits information for one patient at a time. - When the patient is the subscriber, put their details in the `subscriber` object.
- When the patient is the dependent, put the subscriber's details in the `subscriber` object and the patient's details in the `dependents` array.
|
| `41` | Authorization/Access Restrictions | The problem is either:- An issue with the `provider.npi` or `provider.federalTaxpayersIdNumber`. This typically indicates that the provider isn't properly [enrolled](https://www.stedi.com/docs/healthcare/credentialing-and-enrollment) with the payer.
- An issue with the `portalPassword` or `portalUsername` you provided.
|
| `42` | Unable to Respond at Current Time | The payer can't respond to your request. This is typically a temporary issue with the payer's system, such as downtime, but it can also be an extended outage. We recommend retrying immediately and continuing to retry for up to 2 minutes. Learn more about our [recommended retry strategy](/healthcare/eligibility-troubleshooting#payer-connectivity-issues) for payer connectivity issues. |
| `79` | Invalid Participant Identification | There is a problem connecting with this payer. Contact Stedi support. |
| `80` | No Response received - Transaction Terminated | The payer can't respond to your request. This is typically a temporary issue with the payer's system, such as downtime, but it can also be an extended outage. We recommend retrying immediately and continuing to retry for up to 2 minutes. Learn more about our [recommended retry strategy](/healthcare/eligibility-troubleshooting#payer-connectivity-issues) for payer connectivity issues. |
| `T4` | Payer Name or Identifier Missing | The problem is either:- An issue with the `tradingPartnerName` or `tradingPartnerServiceId`. Check the [Payer Network](https://www.stedi.com/healthcare/network) to ensure you're using valid values.
- A payer processing issue. If the issue persists, contact Stedi support to resolve.
|
#### Provider
You may receive the following types of errors at the `provider` level.
| Code | Description | Possible causes and resolutions |
| ---- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `15` | Required application data missing | The payer needs more information about the provider requesting the eligibility check. Try including the `provider.taxId`, typically their EIN or SSN. |
| `41` | Authorization/Access Restrictions | The problem is either: - An issue with the `provider.npi` or `provider.federalTaxpayersIdNumber`. This typically indicates that the provider isn't properly [enrolled](/healthcare/credentialing-and-enrollment) with the payer.
- An issue with the `portalPassword` or `portalUsername` you provided.
- The payer may require other [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment).
|
| `43` | Invalid/Missing Provider Identification | The problem is either: - The `provider.npi` isn't registered correctly with the payer.
- The payer requires an agreement to begin processing eligibility checks for this provider.
Check the [Payer Network](https://www.stedi.com/healthcare/network) to determine whether this payer requires transaction enrollment for eligibility checks. - If yes, you must submit a [transaction enrollment request](/healthcare/transaction-enrollment) for the provider.
- If not, the payer may still require other [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment).
|
| `44` | Invalid/Missing Provider Name | The provider's NPI is registered with an incorrect name for this payer. - Verify that the `provider.organizationName` or the `provider.firstName` and `provider.lastName` are correct. If so, the provider must contact the payer directly to resolve this issue due to PHI/HIPAA guidelines.
- The payer may require other [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment).
|
| `45` | Invalid/Missing Provider Specialty | The provider's NPI isn't registered with the payer under the correct specialty. The provider must contact the payer directly to resolve this issue due to PHI/HIPAA guidelines. The payer may require other [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment). |
| `46` | Invalid/Missing Provider Phone Number | The provider's phone number doesn't match the one registered with the payer or the one in the NPPES system. The provider must contact the payer directly to resolve this issue because of PHI/HIPAA guidelines. The payer may require other [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment). |
| `47` | Invalid/Missing Provider State | The `provider.address` either doesn't match the address registered with the payer or it doesn't match the provider's address in the NPPES system. - Ensure the information in `provider.address` is correct.
- If so, the provider must contact the payer directly to resolve this issue due to PHI/HIPAA guidelines. The payer may require other [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment).
|
| `48` | Invalid/Missing Referring Provider Identification Number | The referring provider (specified in `subscriber.providerIdentifier`) either: - Isn't enrolled correctly with the payer. Contact Stedi support to resolve.
- Isn't registered with the payer's health plans. The provider must contact the payer directly to complete the registration process.
- Must complete additional [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment) with the payer.
|
| `50` | Provider Ineligible for Inquiries | The provider requesting the eligibility check isn't registered with the payer for the service type in `encounter.serviceTypeCodes`. - Ensure the `provider.npi` and `encounter.serviceTypeCodes` are correct.
- If so, the provider must contact the payer directly to complete the registration process. Contact Stedi support with questions.
|
| `51` | Provider Not on File | The provider isn't registered with the payer. - Ensure the `provider.npi` is correct.
- If so, the provider must contact the payer directly to complete the registration process. This can include [credentialing and/or enrollment](/healthcare/credentialing-and-enrollment). Contact Stedi support with questions.
|
| `79` | Invalid Participant Identification | There is a problem connecting with this payer. Contact Stedi support. |
| `97` | Invalid or Missing Provider Address | The payer requires the address for the provider requesting the eligibility check. Retry with the provider's complete address in the `provider.address` object. |
| `T4` | Payer Name or Identifier Missing | The problem is either: - An issue with the `tradingPartnerName` or `tradingPartnerServiceId`. Check the [Payer Network](https://www.stedi.com/healthcare/network) to ensure you're using valid values.
- A payer processing issue. If the issue persists, contact Stedi support to resolve.
|
#### Subscriber
You may receive the following types of errors at the `subscriber` level.
| Code | Description | Possible causes and resolutions |
| ---- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `15` | Required application data missing | - The payer likely needs more information about the subscriber to complete the eligibility check. We recommend providing the subscriber's `memberId`, `dateOfBirth`, `firstName`, and `lastName`. Given this information, all payers must return benefits details as long as they can find a unique match for the member within their system. Visit [patient information](/healthcare/send-eligibility-checks#patient-information) to learn more.
- Try including the `provider.taxId`, typically their EIN or SSN.
|
| `33` | Input Errors | The request doesn't meet the payer’s requirements, which usually means it doesn't contain enough information to identify the patient. We recommend providing the subscriber's `memberId`, `dateOfBirth`, `firstName`, and `lastName`. Given this information, all payers must return benefits details as long as they can find a unique match for the member within their system. Visit [patient information](/healthcare/send-eligibility-checks#patient-information) to learn more. |
| `35` | Out of Network | The subscriber isn't in the provider's network. - Verify that the `provider.npi` is valid.
- If yes, contact the payer for clarification.
|
| `42` | Unable to Respond at Current Time | The payer can't respond to your request. This is typically a temporary issue with the payer's system, such as downtime, but it can also be an extended outage. We recommend retrying immediately and continuing to retry for up to 2 minutes. Learn more about our [recommended retry strategy](/healthcare/eligibility-troubleshooting#payer-connectivity-issues) for payer connectivity issues. |
| `43` | Invalid/Missing Provider Identification | The problem is either: - The `provider.npi` isn't registered correctly with the payer.
- The payer requires an agreement to begin processing eligibility checks for this provider.
Check the [Payer Network](https://www.stedi.com/healthcare/network) to determine whether this payer requires transaction enrollment for eligibility checks. - If yes, you must submit a [transaction enrollment request](/healthcare/transaction-enrollment) for the provider.
- If not, the payer may still require other [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment). Contact Stedi support to determine next steps.
|
| `45` | Invalid/Missing Provider Specialty | The `provider.npi` isn't registered with the payer under the correct specialty. The provider must contact the payer directly to resolve this issue due to PHI/HIPAA guidelines. |
| `47` | Invalid/Missing Provider State | The `provider.address` either doesn't match the address registered with the payer, or it doesn't match the provider's address in the NPPES system. - Ensure the information in `provider.address` is correct.
- If so, the provider must contact the payer directly to resolve this issue due to PHI/HIPAA guidelines.
|
| `48` | Invalid/Missing Referring Provider Identification Number | The referring provider (specified in `subscriber.providerIdentifier`) either: - Isn't enrolled correctly with the payer. Contact Stedi support to resolve.
- Isn't registered with the payer's health plans. The provider must contact the payer directly to complete the registration process. Contact Stedi support with questions.
|
| `49` | Provider is Not Primary Care Physician | The payer doesn’t list the provider as a primary care physician but requires them to be one. The provider or the patient must contact the payer to update their records. |
| `51` | Provider Not on File | The provider isn't registered with the payer. - Ensure the `provider.npi` is correct.
- If so, the provider must contact the payer directly to complete the registration process. This can include [credentialing and/or enrollment](/healthcare/credentialing-and-enrollment). Contact Stedi support with questions.
|
| `52` | Service Dates Not Within Provider Plan Enrollment | The provider wasn't registered with the patient's health plan on the date of service listed in the eligibility check. - Verify that the `provider.npi` and the service dates in the `encounter` object are correct.
- If so, the provider must contact the payer directly to resolve this issue.
|
| `53` | Inquired Benefit Inconsistent with Provider Type Enrollment | The provider isn't registered with the payer to perform the requested benefit type. Some payers only return benefits that match the provider's taxonomy code.- Verify that the `provider.npi` is correct.
- Verify that the `serviceTypeCodes` or the `procedureCode` and `productOrServiceIDQualifier` in the `encounter` object are correct.
- Check the provider taxonomy you sent in `provider.referenceIdentification`. It should match what's recorded in the payer's system.
- If the issue persists, the provider must contact the payer directly to resolve.
|
| `54` | Inappropriate Product/Service ID Qualifier | You provided an invalid `encounter.productOrServiceIDQualifier`. Update the request and resubmit. |
| `55` | Inappropriate Product/Service ID | You provided an invalid `encounter.procedureCode`. Update the request and resubmit. |
| `56` | Inappropriate Date | The service dates in the `encounter` object are incorrect or are formatted incorrectly. . - Dates must be in YYYYMMDD format.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers do support dates further in the future, especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `57` | Invalid/Missing Date(s) of Service | The service dates in the `encounter` object are missing, incorrect, or formatted incorrectly. - Dates must be in YYYYMMDD format.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers do support dates further in the future, especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `58` | Invalid/Missing Date-of-Birth | The payer needs the subscriber's date of birth for identification. - Include `subscriber.dateOfBirth` in the request.
- The date should be in YYYYMMDD format.
|
| `60` | Date of Birth Follows Date(s) of Service | The date(s) of service you provided are earlier than the subscriber's date of birth. - Check the service dates in the `encounter` object.
- Check the `subscriber.dateOfBirth`.
- If this eligibility check is for a newborn, resubmit it with the mother's information instead.
|
| `61` | Date of Death Precedes Date(s) of Service | The date(s) of service you provided are after the patient's date of death. - Check the service dates in the `encounter` object.
- Note that if you don't provide a service date in the request, the payer defaults to using the current date in their timezone.
|
| `62` | Date of Service Not Within Allowable Inquiry Period | The payer doesn't support the date(s) of service you provided.- Check the service dates in the `encounter` object.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers do support dates further in the future, especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `63` | Date of Service in Future | Some payers don't support future date(s) of service.- Check the service dates in the `encounter` object.
- Check the payer's specific requirements.
|
| `69` | Inconsistent with Patient’s Age | The diagnosis codes provided don't match the patient's age. - Check the `subscriber.dateOfBirth`.
- Check any `subscriber.healthCareCodeInformation[].diagnosisCode` values.
|
| `70` | Inconsistent with Patient’s Gender | The procedure codes provided are inconsistent with the patient's gender. - Check `subscriber.gender`.
- Check the values in `encounter.procedureCode` or `encounter.medicalProcedures[].procedureCode`.
|
| `71` | Patient Birth Date Does Not Match That for the Patient on the Database | The subscriber's birth date doesn't match what's in the payer's database. - Check that the `subscriber.dateOfBirth` is correct.
- If so, contact the payer to resolve this issue.
|
| `72` | Invalid/Missing Subscriber/Insured ID | The subscriber's member ID is either missing or invalid.- Check the `subscriber.memberId`.
- Ensure the member ID doesn't include the [Card Issuer Identifier](/healthcare/eligibility-troubleshooting#card-issuer-identifier-80840).
- If you can't locate the correct member ID, try running an [insurance discovery check](/healthcare/insurance-discovery) to retrieve the patient's benefits information instead.
|
| `73` | Invalid/Missing Subscriber/Insured Name | The payer doesn't recognize the subscriber's name. - Verify that the `subscriber.firstName` and `subscriber.lastName` are valid and spelled correctly.
- Enter the patient's name exactly as it appears on their insurance card, if available, including any special or punctuation characters such as apostrophes, hyphens (dashes), or spaces. Review our other best practices for [entering patient names](/healthcare/send-eligibility-checks#patient-names).
|
| `74` | Invalid/Missing Subscriber/Insured Gender Code | The payer requires the subscriber's gender code. Ensure `subscriber.gender` is set to a valid value that matches the payer's records. |
| `75` | Subscriber/Insured Not Found | The payer couldn't locate the subscriber in their database. - We recommend providing the subscriber's `memberId`, `dateOfBirth`, `firstName`, and `lastName`. Given this information, all payers must return benefits details as long as they can find a unique match for the member within their system.
- Enter the patient's name exactly as it appears on their insurance card, if available, including any special or punctuation characters such as apostrophes, hyphens (dashes), or spaces. Review our other best practices for [entering patient names](/healthcare/send-eligibility-checks#patient-names).
- Sometimes patients provide outdated insurance information for the wrong payer. If the issue persists, try running an [insurance discovery check](/healthcare/insurance-discovery) to retrieve the patient's benefits information instead.
|
| `76` | Duplicate Subscriber/Insured ID Number | The payer found another member with the same member ID in their database. Ensure the `subscriber.memberId` is correct. |
| `78` | Subscriber/Insured Not in Group/Plan identified | The subscriber isn't in the specified health plan. - Verify that the `subscriber.memberId` and `subscriber.groupNumber` are correct.
- If so, contact the payer directly to resolve this issue.
|
| `98` | Experimental Service or Procedure | Contact the payer for guidance. |
| `Aa` | Authorization Number Not Found | The prior authorization number the payer has on file doesn't match the one you sent. Verify that the `encounter.priorAuthorizationOrReferralNumber` is correct. |
| `AE` | Requires Primary Care Physician Authorization | The payer requires a prior authorization number. Add the `encounter.priorAuthorizationOrReferralNumber` to your request and resubmit. |
| `AF` | Invalid/Missing Diagnosis Code(s) | The payer requires one or more diagnosis codes, or the diagnosis codes you provided are invalid. Ensure the information in the `subscriber.healthCareCodeInformation[]` array is correct. |
| `AG` | Invalid/Missing Procedure Code(s) | The payer requires a procedure code or the procedure code you provided is invalid. Ensure `encounter.productOrServiceIDQualifier` and `encounter.procedureCode` are set to valid values. |
| `AO` | Additional Patient Condition Information Required | Contact the payer for guidance. |
| `CI` | Certification Information Does Not Match Patient | The prior authorization number the payer has on file doesn't match the one you sent. Verify that the `encounter.priorAuthorizationOrReferralNumber` is correct. |
| `E8` | Requires Medical Review | Contact the payer for guidance. |
| `IA` | Invalid Authorization Number Format | The `encounter.priorAuthorizationOrReferralNumber` wasn't formatted correctly. |
| `MA` | Missing Authorization Number | You must include a previously issued referral or authorization number in your request. Set the `encounter.referenceIdentificationQualifier` and `encounter.priorAuthorizationOrReferralNumber` properties and resubmit. |
#### Dependents
You may receive the following errors at the `dependents` level.
| Code | Description | Possible causes and resolutions |
| ---- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `15` | Required application data missing | - The payer needs more information about the dependent to complete the eligibility check. We recommend providing the dependent's `firstName`, `lastName`, and `dateOfBirth`, when possible. Many payers return errors when the dependent's date of birth is missing.
- Try including the `provider.taxId`, typically their EIN or SSN.
|
| `33` | Input Errors | The request doesn't meet the payer’s requirements, which usually means it doesn't contain enough information to identify the patient. - We recommend providing the subscriber's `memberId`, `dateOfBirth`, `firstName`, and `lastName`.
- We recommend providing the dependent's `firstName`, `lastname`, and `dateOfBirth`.
|
| `35` | Out of Network | The dependent isn't in the provider's network. - Verify that the `provider.npi` is valid.
- If yes, contact the payer for clarification.
|
| `42` | Unable to Respond at Current Time | The payer can't respond to your request. This is typically a temporary issue with the payer's system, such as downtime, but it can also be an extended outage. We recommend retrying immediately and continuing to retry for up to 2 minutes. Learn more about our [recommended retry strategy](/healthcare/eligibility-troubleshooting#retry-strategy) for payer connectivity issues. |
| `43` | Invalid/Missing Provider Identification | The problem is either: - The `provider.npi` isn't registered correctly with the payer.
- The payer requires an agreement to begin processing eligibility checks for this provider.
Check the [Payer Network](https://www.stedi.com/healthcare/network) to determine whether this payer requires transaction enrollment for eligibility checks. - If yes, you must submit a [transaction enrollment request](/healthcare/transaction-enrollment) for the provider.
- If not, the payer may still require other [credentialing or enrollment processes](/healthcare/credentialing-and-enrollment). Contact Stedi support to determine next steps.
|
| `45` | Invalid/Missing Provider Specialty | The `provider.npi` isn't registered with the payer under the correct specialty. The provider must contact the payer directly to resolve this issue due to PHI/HIPAA guidelines. |
| `47` | Invalid/Missing Provider State Specialty | The `provider.address` either doesn't match the address registered with the payer, or it doesn't match the provider's address in the NPPES system. - Ensure the information in `provider.address` is correct.
- If so, the provider must contact the payer directly to resolve this issue due to PHI/HIPAA guidelines.
|
| `48` | Invalid/Missing Referring Provider Identification Number | The referring provider (specified in `dependents[].providerIdentifier`) either: - Isn't enrolled correctly with the payer. Contact Stedi support to resolve.
- Isn't registered with the payer's health plans. The provider must contact the payer directly to complete the registration process. Contact Stedi support with questions.
|
| `49` | Provider is Not Primary Care Physician | The payer doesn't list the provider as a primary care physician, but requires them to be one. The provider or the patient must contact the payer to update their records. |
| `51` | Provider Not on File | The provider isn't registered with the payer. - Ensure the `provider.npi` is correct.
- If so, the provider must contact the payer directly to complete the registration process. This can include [credentialing and/or enrollment](/healthcare/credentialing-and-enrollment). Contact Stedi support with questions.
|
| `52` | Service Dates Not Within Provider Plan Enrollment | The provider wasn't registered with the patient's health plan on the date of service listed in the eligibility check. - Verify that the `provider.npi` and the service dates in the `encounter` object are correct.
- If so, the provider must contact the payer directly to resolve this issue.
|
| `53` | Inquired Benefit Inconsistent with Provider Type Enrollment | The provider isn't registered with the payer to perform the requested benefit type. Some payers only return benefits that match the provider's taxonomy code. - Verify that the `provider.npi` is correct.
- Verify that the `serviceTypeCodes` or `procedureCode` and `productOrServiceIDQualifier` in the `encounter` object are correct.
- Check the provider taxonomy in `provider.referenceIdentification` to ensure it matches what's in the payer's system.
- If the issue persists, the provider must contact the payer directly to resolve.
|
| `54` | Inappropriate Product/Service ID Qualifier | You provided an invalid `encounter.productOrServiceIDQualifier`. Update the request and resubmit. |
| `55` | Inappropriate Product/Service ID | You provided an invalid `encounter.procedureCode`. Update the request and resubmit. |
| `56` | Inappropriate Date | The service dates in the `encounter` object are incorrect or are formatted incorrectly. - Dates must be in YYYYMMDD format.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers do support dates further in the future, especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `57` | Invalid/Missing Date(s) of Service | The service dates in the `encounter` object are missing, incorrect, or formatted incorrectly. - Dates must be in YYYYMMDD format.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers do support dates further in the future, especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `58` | Invalid/Missing Date-of-Birth | The payer needs the dependent's date of birth for identification. - Include `dependents[].dateOfBirth` in the request.
- The date should be in YYYYMMDD format.
|
| `60` | Date of Birth Follows Date(s) of Service | The date(s) of service you provided are earlier than the dependent's date of birth. - Check the service dates in the `encounter` object.
- Check the `dependents[].dateOfBirth`.
- If this eligibility check is for a newborn, resubmit it with the mother's information instead.
|
| `61` | Date of Death Precedes Date(s) of Service | The date(s) of service you provided are after the dependent's date of death. - Check the service dates in the `encounter` object.
- Note that if you don't provide a service date in the request, the payer defaults to using the current date in their timezone.
|
| `62` | Date of Service Not Within Allowable Inquiry Period | The payer doesn't support the date(s) of service you provided. - Check the service dates in the `encounter` object.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers do support dates further in the future, especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `63` | Date of Service in Future | Some payers don't support future date(s) of service. - Check the service dates in the `encounter` object.
- Check the payer's specific requirements.
|
| `64` | Invalid/Missing Patient ID | The payer requires an additional identifier in the `dependents[].additionalIdentification` object. - The required identifier is payer-specific. Check the payer's requirements.
- Don't include the `healthInsuranceClaimNumber` or `medicaidRecipientIdentificationNumber` unless they're different from the member ID.
|
| `65` | Invalid/Missing Patient Name | The payer doesn't recognize the dependent's name. - Ensure that the `dependents[].firstName` and `dependents[].lastName` are valid and spelled correctly.
- Enter the patient's name exactly as it appears on their insurance card, if available, including any special or punctuation characters such as apostrophes, hyphens (dashes), or spaces. Review our other best practices for entering [patient names](/healthcare/send-eligibility-checks#patient-names).
|
| `66` | Invalid/Missing Patient Gender Code | The payer requires the dependent's gender code. Ensure `dependents[].gender` is set to a valid value that matches the payer's records. |
| `67` | Patient Not Found | The payer couldn't locate the dependent in their database. - We recommend providing the dependent's `firstName`, `lastName`, and `dateOfBirth`.
- Enter the patient's name exactly as it appears on their insurance card, if available, including any special or punctuation characters such as apostrophes, hyphens (dashes), or spaces. Review our other best practices for entering [patient names](/healthcare/send-eligibility-checks#patient-names).
- Sometimes patients provide outdated insurance information for the wrong payer. If the issue persists, try running an [insurance discovery check](/healthcare/insurance-discovery) to retrieve the patient's benefits information instead.
|
| `68` | Duplicate Patient ID Number | The payer found another member with the same member ID in their database. Ensure the `subscriber.memberId` is correct. |
| `69` | Inconsistent with Patient’s Age | The diagnosis codes provided don't match the patient's age. - Check the `dependents[].dateOfBirth`.
- Check any `dependents[].healthCareCodeInformation[].diagnosisCode` values.
|
| `70` | Inconsistent with Patient’s Gender | The procedure codes provided are inconsistent with the patient's gender. - Check `dependents[].gender`.
- Check the values in `encounter.procedureCode` or `encounter.medicalProcedures[].procedureCode`.
|
| `71` | Patient DOB Does Not Match That for the Patient on the Database | The dependent's birth date doesn't match what's in the payer's database. - Check that the `dependents[].dateOfBirth` is correct.
- If so, contact the payer to resolve this issue.
|
| `77` | Subscriber Found, Patient Not Found | The payer identified the subscriber in their database, but not the dependent.- We recommend providing the dependent's `firstName`, `lastName`, and `dateOfBirth`.
- Enter the patient's name exactly as it appears on their insurance card, if available, including any special or punctuation characters such as apostrophes, hyphens (dashes), or spaces. Review our other best practices for entering [patient names](/healthcare/send-eligibility-checks#patient-names).
- If the dependent has a unique member ID, you must submit their information in the `subscriber` object instead.
|
| `98` | Experimental Service or Procedure | Contact the payer for guidance. |
| `AA` | Authorization Number Not Found | The payer didn't recognize the prior authorization number you provided. Ensure the `encounter.priorAuthorizationOrReferralNumber` is correct. |
| `AE` | Requires Primary Care Physician Authorization | The payer requires a prior authorization number. Add the `encounter.priorAuthorizationOrReferralNumber` to your request and resubmit. |
| `AF` | Invalid/Missing Diagnosis Code(s) | The payer requires diagnosis codes, or the diagnosis codes you provided were invalid. Ensure the information in the `dependents[].healthCareCodeInformation[]` array is correct. |
| `AG` | Invalid/Missing Procedure Code(s) | The payer requires a procedure code or the procedure code you provided is invalid. Ensure `encounter.productOrServiceIDQualifier` and `encounter.procedureCode` are set to valid values. |
| `AO` | Additional Patient Condition Information Required | Contact the payer for guidance. |
| `CI` | Certification Information Does Not Match Patient | The prior authorization or referral number the payer has on file for the patient doesn't match the one you sent. Verify that the `encounter.priorAuthorizationOrReferralNumber` is correct. |
| `E8` | Requires Medical Review | Contact the payer for guidance. |
| `IA` | Invalid Authorization Number Format | The `encounter.priorAuthorizationOrReferralNumber` wasn't formatted correctly. |
| `MA` | Missing Authorization Number | You must include a previously issued referral or authorization number in your request. Set the `encounter.referenceIdentificationQualifier` and `encounter.priorAuthorizationOrReferralNumber` properties and resubmit. |
### Card Issuer Identifier (80840)
All health plans use (80840) as the first five digits of the Card Issuer Identifier.
This is a placeholder value used for standards compliance only, and you shouldn't pass it in an electronic eligibility check. However, many providers and OCR systems accidentally pass (80840) in other eligibility check fields. For example, they may try to pass this value as a subscriber or dependent ID, causing an [AAA rejection](#payer-aaa-errors) from the payer.
To prevent these types of mistakes, Stedi automatically suppresses any string containing (80840) in the following fields:
| JSON | X12 EDI |
| ----------------------------------------------------- | ----------------------------------------------------- |
| `subscriber.memberId` | Loop 2100C `NM109` Subscriber Primary Identifier |
| Any property in `subscriber.additionalIdentification` | Loop 2100C `REF02` Subscriber Supplemental Identifier |
| Any property in `dependent.additionalIdentification` | Loop 2100D `REF02` Dependent Supplemental Identifier |
If the payer's eligibility response returns an AAA error, Stedi returns the following warning:
```
The field {FIELD} contains the string "(80840)", which is a known
placeholder prefix for a field that should not be provided in {FIELD}.
We have omitted that value in the request, and the request failed.
Please locate the correct value for {FIELD} and resubmit.
```
To correct this error, read the documentation for the corresponding field, locate the correct value, and resubmit the eligibility check.
### SOAP requests
Our [Real-Time Eligibility Check SOAP](/api-reference/healthcare/post-healthcare-eligibility-soap) endpoint respects the error handling rules defined in the [CAQH CORE vC2.2.0 Rule](https://www.caqh.org/core/connectivity).
At a high level, you can experience errors in the following categories:
* [Authentication errors](#authentication-errors): Either your API key, your Stedi account ID, or both are invalid.
* [SOAP faults](#soap-faults): Issues with the request `Envelope` or `Header` elements, such as malformed XML.
* [CORE-compliant errors](#core-compliant-errors): The request don't conform to CAQH CORE rules for eligibility checks.
* [X12 EDI validation errors](#x12-edi-validation-errors): The X12 EDI transaction doesn't match the required format.
* [Payer `AAA` errors](#payer-aaa-errors): Errors from the payer indicating issues with processing your request.
#### Authentication errors
If the `wsse:Username` or `wsse:Password` values are incorrect within the `Header` element:
* Stedi returns an HTTP `401` status code.
* The response includes an `ErrorCode` element set to `UnAuthorized`.
The following example shows an authentication error response:
```xml
CoreEnvelopeError
RealTime
01987b7e-56cc-7871-8520-a22721948fb4
2025-08-06T22:23:50Z
2.2.0
UnAuthorized
Invalid username and/or password.
```
#### SOAP faults
SOAP faults indicate issues with the request `Envelope` or `Header` elements, such as malformed XML or missing required elements.
When these errors occur:
* Stedi returns an HTTP `400` status code.
* The response includes a `Fault` element that contains details about the error. The `Fault` element always contains a `Code` and `Reason` element. The `Code` element indicates the source of the error and the `Reason` element provides a description.
The following example shows a SOAP fault response:
```xml
soapenv:Sender
Unable to parse payload as CORE SOAP request
```
Visit the [SOAP Fault documentation](https://www.w3.org/TR/soap12-part1/#soapfault) for more details and a complete list of possible error codes.
#### CORE-compliant errors
These errors typically indicate issues with the `COREEnvelopeRealTimeRequest` element that contains the request body. However, they can sometimes indicate specific issues with the SOAP `Envelope` or `Header` elements, such as an incorrect SOAP version or invalid credentials.
When these errors occur:
* Stedi returns an HTTP `400` status code.
* The `COREEnvelopeRealTimeResponse` element contains an `ErrorCode` and `ErrorMessage` with a description.
* The `Payload` element is empty because Stedi didn't process the eligibility check.
The following example shows a CORE-compliant error response:
```xml
CoreEnvelopeError
RealTime
01987b70-2b7e-7b40-9875-10d3139dcf2a
2025-08-06T22:23:50Z
TestStedi
Stedi
2.2.0
PayloadIDIllegal
Illegal value provided for PayloadID. Must be a valid UUID
```
The following table lists the possible values for `ErrorCode` and and their causes:
| Error Code | Possible Causes |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CORERuleVersionIllegal` | The `CORERuleVersion` element is not set to `2.2.0`. |
| `CORERuleVersionRequired` | The `CORERuleVersion` element is missing from the request. Set this to `2.2.0`. |
| `PayloadIDIllegal` | The `PayloadID` element is not a valid UUID. |
| `PayloadIDRequired` | The `PayloadID` element is missing from the request. This must be a valid UUID. |
| `PayloadIllegal` | The `Payload` element is empty or doesn't contain a valid X12 EDI 270 transaction. |
| `PayloadRequired` | The `Payload` element is missing from the request. This must be a valid X12 EDI 270 transaction. |
| `PayloadTypeIllegal` | The `PayloadType` element is invalid. Set this to `X12_270_Request_005010X279A1`. |
| `PayloadTypeRequired` | The `PayloadType` element is missing from the request. Set this to `X12_270_Request_005010X279A1`. |
| `ProcessingModeIllegal` | The `ProcessingMode` element is not set to `RealTime`. |
| `ProcessingModeRequired` | The `ProcessingMode` element is missing from the request. Set this to `RealTime` for real-time eligibility checks. |
| `ReceiverIDIllegal` | The `ReceiverID` exceeds the maximum length of 50 characters. |
| `ReceiverIDRequired` | The `ReceiverID` element is missing from the request. Visit the [Request](/api-reference/healthcare/post-healthcare-eligibility-soap#request) reference documentation for guidance on which identifier to use. |
| `SenderIDIllegal` | The `SenderID` exceeds the maximum length of 50 characters. |
| `SenderIDRequired` | The `SenderID` element is missing from the request. Visit the [Request](/api-reference/healthcare/post-healthcare-eligibility-soap#request) reference documentation for guidance on which identifier to use. |
| `TimeStampIllegal` | The `TimeStamp` element is not in the correct format. It must be in ISO 8601 format, such as `2024-07-28T12:00:00Z`. |
| `TimeStampRequired` | The `TimeStamp` element is missing from the request. |
| `UnAuthorized` | The request is unauthorized. This can happen if the `wsse:UsernameToken` is missing or invalid, or if the API key is incorrect. |
| `VersionMismatch` | The SOAP version in the request does not match the expected version. |
#### X12 EDI validation errors
Validation errors occur when the X12 EDI transaction doesn't conform to the expected [270 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-inquiry-x279a1/01GRYB6GTDJ4MEP5Z16CGMQWT6) or contains invalid data.
When there are validation errors, Stedi returns an HTTP `400` status code. There are two possible error cases:
* **Invalid EDI envelope:** There are issues with the `ISA` or `GS` header. The `ErrorCode` element is set to `PayloadIllegal`, and the `Payload` element is empty because Stedi couldn't parse the request.
```xml
CoreEnvelopeError
RealTime
01987c0b-c8b3-71c1-bd6f-8e26725c7110
2025-08-06T22:23:50Z
RECEIVER-ID
SENDER-ID
2.2.0
PayloadIllegal
Error while getting metadata for an X12 file: Error reading EDI: Invalid ISA: ISA-11 must be 'U' for interchange control versions earlier than 00402
```
* **Invalid EDI transaction:** Stedi successfully parsed the EDI envelope, but there are validation issues with the rest of the transaction. The `ErrorCode` element is set to `Success`, and the `Payload` element contains a 999 Implementation Acknowledgment describing the errors. This 999 is usually from Stedi, but it can also be from the payer.
```xml
X12_999_Response_005010X231A1
RealTime
01987c11-ae2e-7f63-801d-cb3529f45952
2025-08-06T22:23:50Z
RECEIVER-ID
SENDER-ID
2.2.0
Success
```
# Overview
Source: https://www.stedi.com/docs/healthcare/eligibility-workflows-overview
***
title: Overview
sidebarTitle: 'Overview'
------------------------
Eligibility refers to a patient's qualification to receive specific medical benefits, services, or coverage under their health plan.
Stedi allows you to reliably determine patient eligibility, even when the patient doesn't know or can't provide accurate insurance information. Once you integrate with Stedi, you can use the UI tools in Eligibility Manager to test, troubleshoot, and monitor your entire eligibility pipeline.
## Eligibility workflows
Here's an overview of the eligibility workflows you can automate with Stedi APIs:
* [Eligibility checks](/healthcare/intro-eligibility-checks): Verify a patient's coverage with a specific payer. Eligibility checks return full benefits information from the payer, so they're helpful when you need to determine a patient's financial responsibilities for medical services, such as co-payments, deductibles, and out-of-pocket maximums.
* [Insurance discovery](/healthcare/insurance-discovery): Find a patient's active health plans using their demographic information, such as their name and date of birth. Insurance discovery checks return the same benefits information as a standard eligibility check, making them a great backup for verifying coverage when eligibility checks fail or aren't possible.
* [Coordination of benefits](/healthcare/coordination-of-benefits): Determine whether a patient has multiple, overlapping coverages and if so, which plan is primarily responsible for payment (primacy). COB checks help you submit claims to the correct payer and avoid claim denials.
## Eligibility Manager
[Eligibility Manager](/healthcare/eligibility-manager) helps you track and manage your entire eligibility pipeline. It provides a centralized view of all your eligibility checks, including real-time and batch requests, and helps you efficiently troubleshoot issues and review patient coverage details. With Stedi Agent, you can resolve common errors automatically with the same best practices our Support team uses for troubleshooting.
Within Eligibility Manager, you can also manually submit new eligibility checks and coordination of benefits checks as needed.
## MCP server
Our [Model Context Protocol (MCP) server](/healthcare/mcp-server) defines a set of tools that AI agents can use to perform and troubleshoot eligibility checks through Stedi.
When building agents that work with eligibility data, we recommend using our MCP server. It excels at individual eligibility checks, especially when your agent needs to retrieve coverage data in real time.
# Enhanced claim validation
Source: https://www.stedi.com/docs/healthcare/enhanced-claim-validation
***
title: Enhanced claim validation
sidebarTitle: 'Enhanced validation'
-----------------------------------
Enhanced claim validation uses hundreds of additional *edits* (the industry term for validation rules) to increase claim acceptance rates.
When a claim fails enhanced validation, Stedi does not submit it to the payer. Instead, Stedi returns a synchronous response with a detailed error message you can use to diagnose and fix the issue.
**Enhanced validation is only available for 837P professional claims.**
## Enable enhanced validation
To enable enhanced validation for the [Professional Claims](/api-reference/healthcare/post-healthcare-claims) or [Professional Claims Raw x12](/api-reference/healthcare/post-healthcare-claims-raw-x12), set the `Stedi-Validation` header to `snip`.
There is an **additional cost per claim submission** when you use enhanced validation. Please reach out to support for access and pricing information.
## Example validation error
The following sample error message resulted from a [SNIP validation Level 3](#level-3-balancing) failure. Specifically, the total claim charge amount did not match the total of all service line charge amounts reported in the claim.
```json
{
"errors": [
{
"id": "481",
"note": "The total claim charge amount must balance to the sum of all service line charge amounts reported in the Professional Service (SV1) segments for this claim.",
"loop_context": null,
"validations": [
{
"Any": [
{
"All": [
{
"Rule": "Expected 'C:2300:1300:CLM-02' (100) to be equal to '[\"P:2400:3700:SV1-02\"]' (92)"
}
]
}
]
}
]
}
]
}
```
## Automatic fixes
When you enable enhanced validation, Stedi also automatically fixes common errors before sending the claim. These include invalid date/time formats and character encoding issues.
## Rejection monitoring
Stedi automatically monitors your 277 rejections to proactively build new rules for enhanced validation based on previous failures.
## SNIP validation
SNIP (Strategic National Implementation Process) validation is a set of guidelines established by the Workgroup for Electronic Data Interchange (WEDI) and the Centers for Medicare & Medicaid Services (CMS) to ensure claims meet specific standards and rules.
Stedi's enhanced validation tests SNIP levels 1-7, which include a wide range of requirements.
### Level 1: EDI syntax
Determine whether the generated EDI file meets basic X12 standard syntax rules, such as:
* Are the data elements within the specified maximum and minimum lengths?
* Are all of the required segments and elements present?
* Are all of the loops in the correct order?
* Are delimiters used correctly?
### Level 2: HIPAA syntax
Determine whether the generated EDI file complies with HIPAA-specific rules, such as:
* Are all of the required segments and elements present in the claim? For example, the request must include the billing provider's address information and tax identification number.
* Are all required qualifiers included correctly? For example, the request must include a qualifier code that indicates whether the subscriber is an individual person or an non-person entity, such as a company.
* Are the parent-child relationships between segments and elements correct? For example, the Claim Information loop contains child loops with information about various providers, ambulance pickup/dropoff (if applicable), and the service facility.
### Level 3: Balancing
Determine whether the financial data in the claim is computed correctly, such as whether claim totals match the sum of the service line items.
### Level 4: Situations
Determine whether the claim meets the situational rules specified in the HIPAA implementation guide.
Situational rules describe scenarios where when A information is present, B information must also be present. For example, when a claim is for an accident, the request must include the accident date.
### Level 5: External code sets
Not yet supported.
Determine whether the values from external code sets used in the claim are valid. This includes:
* Code sets such as ICD, CPT, and NDC as well as status codes and adjustment reason codes.
* Code formats. For example, ICD-10 codes must be alphanumeric with a specific length.
### Level 6: Product type/Type of service
Not yet supported.
Determine whether the claim meets the requirements for the specific type of service or product being billed. For example, if the claim is for an ambulance service, does the request include information about the transport reason and distance traveled?
### Level 7: Payer-specific
Determine whether the claim meets additional, payer-specific requirements. For example, Vermont Medicaid requires all uppercase characters in the request. Stedi's enhanced validation checks whether claims to Vermont Medicaid use all uppercase characters and returns a warning if not.
# The Stedi clearinghouse
Source: https://www.stedi.com/docs/healthcare
Automate transactions with APIs that support thousands of payers
***
title: The Stedi clearinghouse
sidebarTitle: Clearinghouse
description: "Automate transactions with APIs that support thousands of payers"
-------------------------------------------------------------------------------
## Eligibility & benefits
Reliably determine eligibility and coordination of benefits, even when patients can't provide accurate insurance information.
Submit 270/271 eligibility checks through the Stedi portal or API in either
JSON or X12 EDI.
Identify coverage overlap and determine payer responsibility for claims
(primacy).
Find active health plans using the patient's demographic data.
Full reference for our Eligibility, Coordination of Benefits, and Insurance
Discovery APIs.
## Claims processing
Submit 837P professional, 837I institutional, and 837D dental claims and 276/277 real-time claim status checks in both JSON and X12 EDI.
Send claims to payers through the API, an SFTP connection, or the Stedi
portal.
Retrieve processed 277CA claim acknowledgments and 835 ERAs from Stedi.
Determine the processing status of existing claims in real time.
Full reference for our Claims, Claim Status, and Reports (277CA and ERA)
APIs.
# Insurance discovery checks
Source: https://www.stedi.com/docs/healthcare/insurance-discovery
***
title: Insurance discovery checks
sidebarTitle: 'Insurance discovery checks'
------------------------------------------
Eligibility checks verify a patient's coverage with a specific payer. But what if you don't know the patient's insurance details or you're not sure whether they have coverage at all? In these situations, you can use an insurance discovery check to search for a patient's active coverage using only their demographic data.
You may need to perform an insurance discovery check when:
* You don't know the payer, such as when a patient doesn't have their insurance card or can't provide insurance details in an urgent care situation.
* One or more eligibility checks failed with an AAA `75` (Subscriber Not Found) or similar error.
* The patient's information is incomplete or outdated, such as when the patient can't provide their member ID.
We recommend using insurance discovery checks as a backup when eligibility checks fail or aren't possible. Because of their limitations, you shouldn't rely on them as your primary method for verifying patient coverage.
## Limitations
Insurance discovery checks have the following limitations:
* **Match rates vary:** Insurance discovery checks aren't guaranteed to return a patient's active health plans 100% of the time - especially when the request doesn't include key demographic information like the patient's address or Social Security Number (SSN).
* **Dental use cases aren't supported:** Insurance discovery checks only reliably identify active medical coverage. Some payers may return dental coverage (service type code `35`) in their response, but insurance discovery checks won't return results for dental-only payers even if the patient has coverage. Don't use insurance discovery for dental use cases.
* **No retroactive or future coverage:** Insurance discovery checks can only return active coverage for the date of service range provided. For example, if a patient recently switched insurance plans and coverage for the previous plan has ended, the insurance discovery check will only return their new, active plan.
* **No payer primacy:** Insurance discovery checks can't determine payer primacy. You must run a [coordination of benefits (COB) check](/healthcare/coordination-of-benefits) to determine whether the patient has active coverage with additional payers and which payer is responsible for paying claims (primacy).
* **Slower response time:** Insurance discovery checks are slower than real-time eligibility checks and can take up to 120 seconds to return results. This is because Stedi performs an average of 13-16 real-time eligibility checks per insurance discovery check.
## How insurance discovery checks work
Call the [Insurance Discovery Check](/api-reference/healthcare/post-insurance-discovery) endpoint or submit through the [Create insurance discovery check form](https://portal.stedi.com/app/healthcare/insurance-discovery/create) in the Stedi portal.
You should provide as much patient demographic information as possible to increase the chances of finding matching coverage. You'll also include information like the provider's NPI and the date of service, similar to an eligibility check.
The insurance discovery process involves demographic lookups to enrich partial patient details, comparisons across third-party data sources to determine member IDs, and submitting real-time eligibility checks to payers to detect coverage.
Stedi choose the most probable payers based on the patient's demographic details, resulting in 13-16 real-time eligibility checks. Once all checks are complete, Stedi compiles the results into the response.
Stedi returns an array of potential active coverages along with subscriber details and benefits information. You should always review the results to ensure the returned subscriber information matches the demographic information for the patient.
If there's a match, you can use the benefits information to determine the patient’s eligibility for services. You generally shouldn't need to perform a follow-up eligibility check since the insurance discovery response includes the same benefits information.
## Enrollment requirements
Before you can perform insurance discovery checks, you must complete [transaction enrollment](/healthcare/transaction-enrollment) for Payer ID: DISCOVERY.
### Medicaid Provider ID
A Medicaid Provider ID is a unique identification number assigned to a healthcare provider when they enroll with a state Medicaid program. It's different than a provider's [National Provider Identifier (NPI)](/healthcare/national-provider-identifier), which is assigned by the federal government. If a provider works in multiple states, they'll have different Medicaid IDs for each state.
Medicaid Provider IDs aren't required for transaction enrollment with Stedi, but they can enhance insurance discovery check results for certain payers. To add Medicaid Provider IDs to transaction enrollment requests, please email [enrollments@stedi.com](mailto:enrollments@stedi.com) with a CSV file containing the NPI and Medicaid ID(s) for each provider.
Many state Medicaid agencies have a provider lookup tool you can use to find a provider's Medicaid Provider ID. For example, for providers who practice in Texas, you can use the [Texas Medicaid & Healthcare Partnership Provider lookup tool](https://opl.tmhp.com/) to search for enrolled providers. You can also call the state Medicaid agency to request a provider's ID.
## Required patient information
You should provide as much patient demographic information as possible when submitting insurance discovery checks. The more information you provide, the more likely Stedi is to find matching coverage.
### Minimum required
At a minimum, you must provide the patient's:
* First name
* Last name
* Date of birth (DOB)
However, match rates will be very low with only this basic information. The reason is that the patient information provided must resolve to a single member to return results. Unless the name is extremely uncommon, a name + DOB is likely to match multiple members and result in no matches.
### Recommended
In addition to the patient's name and DOB, we **strongly recommend** providing as much of the following additional information as possible.
* Current address or previous addresses - especially the patient's ZIP code, as this helps narrow down the list of probable payers. ZIP code search isn't an exact match, so even the first 3-4 digits of the patient's current zip code can help improve the results. If the patient's current address isn't available, you can try a full or partial zip code from one of the patient's previous addresses or even one in close proximity.
* Social Security Number (SSN) - The patient's full SSN is preferred, but even the last 4 digits of the SSN can help narrow down matching coverage.
* Gender
## Manual submission
You can submit insurance discovery checks through the [Create insurance discovery check](https://portal.stedi.com/app/healthcare/insurance-discovery/create) form in the Stedi portal.
Unlike eligibility checks, Stedi doesn't display historical insurance discovery checks in the UI for review.
## API submission
You can submit an insurance discovery check using the [Insurance Discovery Check](/api-reference/healthcare/post-insurance-discovery) endpoint.
### Request
The following example shows the payload for an insurance discovery check.
{/* schema:InsuranceDiscoveryCheckRequestContent */}
```json
{
"provider": {
"npi": "1999999984"
},
"encounter": {
"beginningDateOfService": "20250326",
"endDateOfService": "20250328"
},
"subscriber": {
"dateOfBirth": "20010925",
"firstName": "Jane",
"lastName": "Doe",
"address": {
"address1": "1 MAIN ST",
"address2": "UNIT 1",
"city": "ANYTOWN",
"state": "MO",
"postalCode": "12341"
}
}
}
```
### Response
Stedi's synchronous response to the [Insurance Discovery Check](/api-reference/healthcare/post-insurance-discovery) endpoint can take up to 120 seconds to return, though it's often faster.
The synchronous response can have one of two `status` values:
* `COMPLETE` - Stedi has completed the insurance discovery check for the patient. If Stedi finds coverage for the patient, the `items` array will contain the results. If Stedi doesn't find any coverage for the patient, the `items` array will be empty.
* `PENDING` - Stedi is still processing the insurance discovery check for the patient. You can use the `discoveryId` in the response to [retrieve the results asynchronously](#retrieve-results-asynchronously).
The following example response shows a `PENDING` insurance discovery check. In this case, you would use the `discoveryId` to retrieve the results asynchronously.
{/* schema:InsuranceDiscoveryCheckResponseContent */}
```json Insurance discovery check in progress
{
"discoveryId": "12345678-abcd-4321-efgh-987654321abc",
"meta": {
"applicationMode": "production",
"traceId": "1-abcdef12-123456789abcdef123456789"
},
"status": "PENDING",
"items": []
}
```
The following example response shows a `COMPLETE` insurance discovery check. Stedi found one instance of potential matching coverage for the patient, Jane Doe. Insurance discovery checks only return active coverage for the date of service range provided, so any old plans with expired coverage aren't included in the results.
Information about the potential match is available in the `items` array.
* The `payer` is Aetna.
* The patient in the request, Jane, is a dependent on the Aetna plan because her demographic information appears in the `dependent` object in the response.
* The `confidence.level` is marked as `REVIEW_NEEDED`, because the dependent's last name is slightly different from the patient's last name in the insurance discovery request. However, all of the other demographic details in the dependent object - first name, date of birth, address - match the patient from the request. The two-part last name, Smith Doe, appears to be the complete version of the last name in the request, Doe. Based on this information, we can confirm that this is active coverage for the patient.
* The `benefitsInformation object` (truncated to keep this example concise) contains the patient's benefits details. For example, the patient has active medical coverage under their health plan for the service dates in the request. Visit [Determine patient benefits](/healthcare/eligibility-active-coverage-benefits) to learn more about interpreting the benefits information in the insurance discovery check response.
* Payer names and IDs aren't normalized, so you'll need to handle matching these results to Stedi's Payer Network or your own internal payer list.
{/* schema:InsuranceDiscoveryCheckResponseContent */}
{/* replace:// truncated for brevity: */}
```json Insurance discovery check completed
{
"coveragesFound": 1,
"discoveryId": "e856b480-0b41-11f0-aee6-fc0434004bca",
"items": [
{
"provider": {
"providerName": "THE DOCTORS OFFICE",
"entityType": "Non-Person Entity",
"npi": "1999999984"
},
"subscriber": {
"memberId": "J9606211996",
"firstName": "JOHN",
"lastName": "DOE",
"groupNumber": "012345607890008",
"groupDescription": "SAMPLE HEALTH GROUP",
"insuredIndicator": "Y"
},
"dependent": {
"firstName": "JANE",
"lastName": "SMITH DOE",
"gender": "F",
"dateOfBirth": "20010925",
"planNumber": "0123654",
"relationToSubscriber": "Child",
"relationToSubscriberCode": "19",
"address": {
"address1": "1 MAIN ST",
"address2": "UNIT 1",
"city": "ANYTOWN",
"state": "MO",
"postalCode": "12341"
}
},
"payer": {
"entityIdentifier": "Payer",
"entityType": "Non-Person Entity",
"lastName": "Aetna",
"name": "Aetna",
"payorIdentification": "100003"
},
"planInformation": {
"planNumber": "0123654"
},
"planDateInformation": {
"planBegin": "20250101",
"eligibilityBegin": "20250101",
"service": "20250327"
},
"benefitsInformation": [
{
"code": "1",
"name": "Active Coverage",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": [
"30"
],
"serviceTypes": [
"Health Benefit Plan Coverage"
],
"insuranceTypeCode": "PS",
"insuranceType": "Point of Service (POS)",
"planCoverage": "Aetna Choice POS II",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable"
},
// truncated for brevity
{
"code": "W",
"name": "Other Source of Data",
"benefitsRelatedEntities": [
{
"entityIdentifier": "Payer",
"entityType": "Non-Person Entity",
"entityName": "AETNA",
"address": {
"address1": "PO BOX 981106",
"city": "EL PASO",
"state": "TX",
"postalCode": "79998"
}
}
]
}
],
"confidence": {
"level": "REVIEW_NEEDED",
"reason": "This record was identified as a low confidence match due to a last name mismatch."
}
}
],
"meta": {
"applicationMode": "production",
"traceId": "1-67e5a730-75011daa6caebf3c6595bf7c"
},
"status": "COMPLETE"
}
```
### Concurrency limit
Visit [Concurrency limits](/api-reference#concurrency-limits) for more information.
### Recommended API clients
You may want to use an API client to make testing and debugging easier.
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.
Visit [API clients](/api-reference#api-clients) for a list of recommended clients you can use instead.
## Retrieve results asynchronously
If the synchronous insurance discovery response indicates that the search is still `PENDING`, you can use the `discoveryId` to retrieve the complete results asynchronously from the [Insurance Discovery Check Results](/api-reference/healthcare/get-insurance-discovery-results) endpoint.
You can begin polling immediately after receiving the `PENDING` status response from the synchronous endpoint. Like the synchronous endpoint, the Insurance Discovery Check Results endpoint can take up to 120 seconds to return a response.
It's unlikely for the insurance discovery process to take more than a few minutes, so it's rare to have to poll the asynchronous endpoint more than once. However, if you receive a `PENDING` status, you can poll the endpoint immediately again, and continue this polling process until the status changes to `COMPLETE`.
Note that you should only expect to retrieve checks submitted within the last 24 hours. After 24 hours, the results may no longer be available.
## No matches
Insurance discovery checks can return zero matches for a patient even when they have active coverage.
```json
{
"coveragesFound": 0,
"discoveryId": "0197a79a-ed75-77c3-af58-8ece597ea0be",
"items": [],
"meta": {
"applicationMode": "production",
"traceId": "1-685c0f14-1b559a954f0bd0127110d161"
},
"status": "COMPLETE"
}
```
Common reasons for zero matches include:
* Recommended demographic data, like SSN or ZIP code, was missing from the request. You should provide as much [patient demographic information](#required-patient-information) as possible to increase the chances of finding matching coverage.
* The patient's data doesn't exactly match what the payer has on file. For example, the patient isn't using their legal name, or their address has changed.
* The payer doesn't support real-time eligibility checks, which makes it impossible for Stedi to determine coverage.
* The patient is covered under a different name, spelling, or demographic variation.
If you think the patient has coverage, try again with corrections or more data. Even small changes like using a partial SSN or legal name can make a difference.
## Coordination of benefits (COB) checks
Insurance discovery checks aren't guaranteed to return all of a patient's active health plans, so a follow-up COB check can help you determine whether the patient has active coverage with additional payers and which payer is responsible for paying claims (primacy).
Once you receive the results of an insurance discovery check, we recommend performing [COB checks](/healthcare/coordination-of-benefits) for the patient using one of their active commercial plans.
# Integrated accounts
Source: https://www.stedi.com/docs/healthcare/integrated-accounts
***
title: Integrated accounts
sidebarTitle: Integrated accounts
---------------------------------
An integrated account is a streamlined version of the Stedi portal that allows healthcare providers to monitor, manage, and troubleshoot their eligibility checks and claims directly. Stedi [Platform Partners](https://www.stedi.com/platform-partners) use integrated accounts to offer their customers this additional functionality without extensive development work.
Here's the typical use case:
1. A provider signs up for an integrated account with Stedi and then installs the Stedi app for their vendor. This process connects the provider's Stedi account to their vendor account.
2. The vendor sends transactions through the Stedi clearinghouse on the provider's behalf.
3. The provider can monitor and manage these transactions in their Stedi account. For example, they can perform manual eligibility checks, view submitted claims, and resubmit denied claims.
This page helps providers create an integrated account and use it in their eligibility and claim submission workflows.
## Account setup
The following steps will help you create and configure an integrated account.
### Create an integrated account
You can create an integrated account with Stedi directly. To create an integrated account:
1. [Create a sandbox](http://stedi.com/create-sandbox).
2. Click **Upgrade**.
3. Select **Integrated Account** and follow the prompts.
### Install Stedi apps
Once you create an integrated account, you can install Stedi apps to quickly connect your account to third-party Revenue Cycle Management (RCM) systems, Practice Management Systems (PMS), Electronic Healthcare Record (EHR) platforms, and other [Platform Partners](https://www.stedi.com/platform-partners).
To browse and install available apps:
1. Go to the [Apps page](https://portal.stedi.com/app/settings/apps) in your account settings.
2. Click an app to view its details and begin the installation process.
3. Click **Generate credentials**. Stedi generates SFTP credentials as well as an API key that you'll use to connect your Stedi account to your to vendor.
4. Follow your vendor's instructions to enter the generated credentials into their system.
Your vendor can now begin sending transactions through Stedi on your behalf.
### Add members
Your integrated account can have many members - a member represents an individual email address used to log into the account. You may want to add additional members so that other individuals in your organization can help manage transactions and troubleshoot issues. Your vendor may also request to be invited to your account, so they can investigate and troubleshoot issues directly during support sessions.
Members can have different roles, depending on the permissions you want them to have within your account. An **Admin** has the highest permissions, and they can access and update all resources in your account, including members and billing details. We recommend assigning most members to the **Operator** role. This role allows members to manage transactions (like claims and eligibility checks) and submit transaction enrollments requests, but not change account settings or billing information.
To add members to an integrated account:
1. Go to the [Members](https://portal.stedi.com/app/settings/members) page in **Account settings**.
2. Click **Invite member**.
3. Enter the email address of the member you want to add and select their role.
4. Click **Send invitation**.
The invited member will receive an email with instructions about how to accept the invitation and log into the account.
Visit [Accounts and billing](/accounts-and-billing#accounts) for complete details about managing your account, including enabling Multi-Factor Authentication (MFA).
### Submit transaction enrollments
You must complete [transaction enrollment](/healthcare/transaction-enrollment) with each payer before you can receive 835 Electronic Remittance Advice (ERA) transactions through Stedi. Transaction enrollment is also required for some other types of transactions, depending on the payer.
After signing up for your integrated account, we recommend:
1. Check the [Payer Network](https://www.stedi.com/healthcare/network) to determine whether your payers require enrollment for the transaction types you want to send and receive. For transactions marked as **Supported, enrollment required**, you must complete the transaction enrollment process before you or your vendor can begin exchanging that transaction type through Stedi.
2. Submit [transaction enrollment requests](/healthcare/transaction-enrollment#create-enrollment-requests) for all required payers.
You can track the status of your transaction enrollment requests from the [Enrollments page](https://portal.stedi.com/app/healthcare/enrollments) in your account.
## Eligibility & benefit verification
In your integrated account, you can:
* Review every historical eligibility check in your account.
* Search and filter eligibility checks by status, Payer ID, date, and error code.
* Edit and retry failed eligibility checks.
* Use the Debug view to systematically troubleshoot failed eligibility checks.
### Run eligibility checks
Stedi stores eligibility check requests in groups called eligibility searches.
When you submit an eligibility check, Stedi creates a new eligibility search record. Every time you retry that eligibility check, Stedi stores the retry details within the existing eligibility search. This creates a clear timeline of troubleshooting efforts for failed requests.
To run a new eligibility check:
1. Go to the [Eligibility searches](https://portal.stedi.com/app/healthcare/eligibility) page and click **+ New eligibility check**.
2. Enter the required information. You can click **Select fields** to include additional information in the request.
3. Click **Submit**.
Stedi runs the eligibility check and stores it in a new eligibility search. Stedi sets the eligibility search to a [status](/healthcare/eligibility-manager#statuses) indicating whether the check was successful.
### MBI lookup
A Medicare Beneficiary Identifier (MBI) is a unique, randomly-generated identifier assigned to individuals enrolled in Medicare. You must include the patient's MBI in every eligibility check you submit to the Centers for Medicare and Medicaid Services.
When patients don't know their MBI, you can perform an MBI lookup using their Social Security Number instead. To perform an MBI lookup:
1. Go to the [Eligibility searches page](https://portal.stedi.com/app/healthcare/eligibility) and click **+ New eligibility check**.
2. Construct an eligibility check request that includes the patient's first name, last name, date of birth, and Social Security Number (SSN). To do this, you'll need to click **Select fields** and check the box next to **Social Security Number (SSN)** under the **Subscriber (required)** section.
3. Set the **Trading partner service ID** to **CMS MBI Lookup**.
4. Click **Submit**.
Stedi uses the patient’s demographic data and SSN to perform an MBI lookup. If there is a match, Stedi submits an eligibility check to CMS. Stedi returns a complete eligibility response from CMS for the patient and returns the patient's MBI as the subscriber's member ID.
Medicare Advantage plans have their own unique member ID, which **isn't** returned in the MBI lookup response. You also shouldn't submit eligibility checks for Medicare Advantage plans to CMS (HETS) - you should submit them to the actual Medicare Advantage plan payer instead.
### Debug and retry eligibility checks
You can edit the request details for failed eligibility checks and resubmit them as many times as you need to get a successful response. For some types of errors, you can use the Stedi Agent to troubleshoot automatically.
Visit [Retry failed eligibility checks](/healthcare/eligibility-manager#retry-failed-eligibility-checks) for complete details.
## Claims processing
You can manage claim submissions in your integrated account, including submitting new claims, tracking existing claims a vendor submitted on your behalf, resubmitting claims, and reviewing 277CA claim acknowledgments (277CA) and 835 Electronic Remittance Advice (ERAs).
### Review claims and claim responses
You can review every claim and claim response in your account on the [Transactions page](https://portal.stedi.com/app/healthcare/transactions).
Click any transaction to view its details. In the **Related transactions** tab, you can find links to all related transactions, such as 277CA and 835 ERA responses. Visit [response types](/healthcare/receive-claim-responses#response-types) for more details about these responses and when you can expect to receive them after claim submission.
### Submit professional claims
You can submit 837P professional claims manually through the [Create professional claim page](https://portal.stedi.com/app/healthcare/claims/create).
The in-app form is based on the CMS-1500 claim form, but it doesn’t support every data element. Specifically, it omits some parts of Item 19 (Additional Claim Information) and all of Item 24 supplemental information (shaded area). If you need this data, you'll need to submit claims directly through SFTP or through your vendor instead.
#### Download CMS-1500 PDF
Stedi automatically generates a [PDF CMS-1500 claim form](https://www.nucc.org/index.php/1500-claim-form-mainmenu-35) for each professional claim.
To download the PDF:
1. Go to the [Transactions page](https://portal.stedi.com/app/healthcare/transactions) and click the claim you want to download.
2. Click **Download CMS 1500 claim PDF**. You can choose to download it either with or without the CMS-1500 form overlay.
Payers have strict requirements for submitted CMS-1500 claim forms. If you plan to send generated PDFs to payers or retain them for your records, we strongly recommend visiting [CMS-1500 Claim Form PDF](/healthcare/cms-1500-claim-form-pdf) for information about the correct printer settings for generated PDFs and general best practices.
### Revise and resubmit claims
You may need to resubmit claims for several reasons, including changes to the patient's coverage, errors in the original claim's information, or appealing a denied claim. You may also need to cancel duplicate claims or claims that were submitted in error.
You can manually revise and resubmit professional and dental claims in your integrated account. To manually resubmit a claim:
1. Go to the [Transactions page](https://portal.stedi.com/app/healthcare/transactions) and click the claim you want to resubmit.
2. Click **Edit and resubmit**. Stedi opens the claim in an interactive editor, with the X12 EDI on the left and the EDI specification on the right.
3. Make any necessary changes to the claim EDI, then click **Review and submit**. Stedi shows a comparison of the original claim and the new claim containing your changes.
4. Click **Resubmit claim** to send the updated claim to the payer.
#### Claim Frequency Code
Set the Claim Frequency Code to one of the following values. In X12 EDI, this is the `Loop 2300 CLM05-03` (Claim Frequency Code) component.
* **Resubmit to Stedi or another payer:** Set to `1` - Admit thru Discharge Claim. Either Stedi rejected the claim due to validation errors, or you're resubmitting the claim to a different payer for the first time. In either case, the payer hasn't yet processed the claim.
* **Correct or replace claims:** Set to `7` - Replacement of Prior Claim. In this case, the payer processed the original claim.
* **Cancel claims:** Set to `8` - Void/Cancel of Prior Claim.
#### Payer Claim Control Number
When correcting, replacing, or canceling claims, you should include the Payer Claim Control Number (sometimes called the ICN) from the original claim for identification. In X12 EDI, this is `Loop 2300 REF02`, where `REF01` = `F8` (Original Reference Number).
* The Payer Claim Control Number is different from the value you sent in the original claim's `Loop 2300 CLM01` (Patient Control Number).
* You can retrieve the Payer Claim Control Number from one of the payer's 277CA claim acknowledgments in `Loop 2200D REF02` when `REF01` is set to `1K` (Payor's Claim Number).
#### Patient Control Number
When correcting or replacing claims, we also recommend setting a new, unique Patient Control Number. In X12 EDI, this is the `Loop 2300 CLM01` element. The payer includes this value in their 835 ERA, allowing you to easily correlate that response with your resubmission.
# Overview
Source: https://www.stedi.com/docs/healthcare/intro-eligibility-checks
***
title: Overview
sidebarTitle: Overview
----------------------
An eligibility check is the process of verifying whether a patient has coverage for specific medical benefits under their health insurance plan. This process allows patients and healthcare providers to determine a patient's financial responsibilities for medical services.
You can send either real-time or batch eligibility checks through Stedi. With real-time checks, you receive the response from the payer in seconds. With batch checks, you can submit up to 1,000 eligibility checks in a single request for Stedi to process asynchronously.
Eligibility checks verify coverage with a specific payer. If you don't know the payer, you can perform an [insurance discovery check](/healthcare/insurance-discovery) instead to find a patient's coverage using their demographic data.
## Real-time eligibility checks
Real-time eligibility checks are ideal for in-person patient visits, telehealth appointments, and other scenarios where you need immediate information about a patient's coverage.
We recommend always starting with real-time checks when integrating with a new payer. This approach allows you to quickly test and refine your pipeline through fast feedback loops. Once you're comfortable with real-time checks, you may also want to start sending asynchronous batch checks to perform periodic refreshes for all or a subset of patients.
Stedi supports sending real-time eligibility checks to payers, in either JSON or X12 EDI format. You can submit requests manually through the Stedi portal or programmatically through the API.
Stedi routes requests to the payer using the most reliable connection. Stedi receives payer responses in X12 EDI and transforms them into JSON to make them easier to ingest into your business systems.
Stedi returns the payer's synchronous response. It contains details about a patient's medical coverage, including the start and end date of the coverage, covered benefits and services, copayments, deductibles, and out-of-pocket maximums.
Learn more about [Real-time eligibility checks](/healthcare/send-eligibility-checks).
## Batch eligibility checks
Batch eligibility checks are a great option as your volume grows. Stedi handles complexity like queuing and retries according to established best practices, so you don't have to build this logic yourself. We recommend using batch checks for bulk workflows that aren't time sensitive, including:
* Monthly or weekly coverage refreshes
* Upcoming appointments
* Sets of thousands or millions of checks that can run in the background
However, batch checks have a longer feedback cycle than real-time checks because you don't receive the payer's response immediately. That's why we strongly recommend starting with [real-time checks](/api-reference/healthcare/post-healthcare-eligibility) when integrating with a new payer or working with eligibility checks for the first time. This approach allows you to ensure that your pipeline is working smoothly before you begin staging batch checks.
You can submit batch eligibility checks manually by uploading CSV files to the Stedi portal or programmatically by sending a request to the [Batch Eligibility Check](/api-reference/healthcare/post-healthcare-batch-eligibility) endpoint. Each batch can contain up to 1,000 eligibility checks.
Stedi processes these batch checks asynchronously, implementing best practices to avoid payer throttling. Stedi routes requests to the payer using the most reliable connection.
The API's synchronous response contains a `batchId` that you can use to retrieve the results of the batch checks using the [Poll Batch Eligibility Checks](/api-reference/healthcare/get-healthcare-polling-eligibility) endpoint.
You can also review the results of batch eligibility checks from the [Eligibility check batches page](https://portal.stedi.com/app/healthcare/checks/batch) in the Stedi portal.
Learn more about [Batch eligibility checks](/healthcare/batch-refresh-eligibility-checks).
## X12 HIPAA format
The Health Insurance Portability and Accountability Act (HIPAA) mandates that eligibility checks be submitted in a standardized format: X12 HIPAA. X12 HIPAA is a type of Electronic Data Interchange (EDI), a data format developed in the 1970s to allow businesses to exchange documents electronically.
While some healthcare institutions can submit eligibility checks directly in X12 HIPAA, many of today's software applications are built to use more modern data formats like JSON. That's why Stedi offers two types of APIs for eligibility checks: one that accepts JSON and automatically converts it to X12 HIPAA behind the scenes, and another that accepts X12 HIPAA directly.
## Billing for eligibility checks
There are four classes of eligibility transactions that are considered non-billable:
1. All eligibility checks you send in [Test Mode](/healthcare/test-mode).
2. All eligibility checks that return `AAA` = `42` or `AAA` = `80` errors, which indicate that the payer is down.
3. All eligibility checks that return `AAA` = `79` errors, which indicate there was a problem connecting to this payer.
4. All API calls that return `4xx` or `5xx` errors.
All other transactions are billed at the usage rates according to your contract.
# Overview
Source: https://www.stedi.com/docs/healthcare/intro-to-claims-processing
***
title: Overview
sidebarTitle: Overview
----------------------
A claim is a request for payment submitted to an insurance company or health plan. It details the medical services rendered to a patient, including information about the diagnosis, treatment, and any procedures performed. The claim is used to determine the reimbursement amount that the submitter (typically a medical provider) should receive from the insurance company.
You can programmatically submit claims and claim status requests through Stedi APIs. You can also submit claims through Stedi's fully-managed SFTP server.
## API claims processing
You can submit most claim types and real-time claim status requests to Stedi APIs in either JSON or X12 EDI format. We recommend this approach when you want to submit claims and real-time claim status requests programmatically without dealing with the complexities of the X12 EDI format.
Stedi supports sending the following transactions to payers:
* 837P professional claim |
[JSON API](/api-reference/healthcare/post-healthcare-claims) | [X12 EDI API](/api-reference/healthcare/post-healthcare-claims-raw-x12)
* 837I institutional claim | [JSON API](/api-reference/healthcare/post-healthcare-institutional-claims)
* 837D dental claim | [JSON API](/api-reference/healthcare/post-healthcare-dental-claims) | [X12 EDI API](/api-reference/healthcare/post-healthcare-dental-claims-raw-x12)
* 276/277 real-time claim status | [JSON API](/api-reference/healthcare/post-healthcare-claim-status) | [X12 EDI API](/api-reference/healthcare/post-healthcare-claim-status-raw-x12)
Stedi automatically translates JSON requests into X12 EDI and validates requests to ensure they comply with HIPAA and the payer's specifications.
Stedi routes requests to the payer. Stedi receives payer responses in X12 EDI and transforms them into JSON to make them easier to ingest into your business systems.
* Stedi returns synchronous claim status responses from the payer in real time.
* You can either poll or listen for event-driven webhooks to discover new 277CA claim acknowledgments and 835 Electronic Remittance Advice (ERAs). Then, you can use Stedi APIs to retrieve these responses in JSON format.
Learn more about API submission for [professional](/healthcare/submit-professional-claims), [institutional](/healthcare/submit-institutional-claims), and [dental](/healthcare/submit-dental-claims) claims.
## SFTP claims processing
We recommend Stedi SFTP when you have an existing system that generates X12 EDI files, and you want to send them through Stedi without completing an API integration.
You can create both test and production SFTP users. Test users can only send claims to Stedi’s test clearinghouse, which helps ensure you never accidentally send test claims to payers while you’re getting up and running.
Connect to Stedi’s server and drop compliant X12 EDI professional, institutional, or dental claim files into the `to-stedi` directory.
Stedi automatically validates the claim data and routes your claims to the test or production clearinghouse.
Stedi places claim responses - 277CA claim acknowledgments and 835 ERAs - into the `from-stedi` directory in X12 EDI format. You can retrieve these responses from the directory at your preferred cadence.
Learn more about [SFTP claim submission](/healthcare/submit-claims-sftp-connection).
## X12 HIPAA format
The Health Insurance Portability and Accountability Act (HIPAA) mandates that claims and claim status requests be submitted in a standardized format: X12 HIPAA. X12 HIPAA is a type of Electronic Data Interchange (EDI), a data format developed in the 1970s to allow businesses to exchange documents electronically.
While some healthcare institutions can submit claims and claim status requests directly in X12 HIPAA, many of today's software applications are built to use more modern data formats like JSON. That's why Stedi offers two types of APIs for claims processing: one that accepts JSON and automatically converts it to X12 HIPAA behind the scenes, and another that accepts X12 HIPAA directly.
# Medicare Beneficiary Identifier (MBI) lookup
Source: https://www.stedi.com/docs/healthcare/mbi-lookup
***
title: Medicare Beneficiary Identifier (MBI) lookup
sidebarTitle: MBI lookup for CMS checks
---------------------------------------
A [Medicare Beneficiary Identifier (MBI)](https://www.cms.gov/training-education/partner-outreach-resources/new-medicare-card/medical-beneficiary-identifiers-mbis) is a unique, randomly-generated identifier assigned to individuals enrolled in Medicare. You must include the patient's MBI in every eligibility check you submit to the Centers for Medicare and Medicaid Services ([payer ID: CMS](https://www.stedi.com/healthcare/network?page=0\&search=CMS\&entry=JDNSN)).
When patients don't know their MBI, you can use Stedi's eligibility APIs to perform an MBI lookup using their Social Security Number instead. Stedi returns a complete eligibility response containing the patient’s coverage status and their MBI for future reference.
There is an additional cost to perform MBI lookups with Stedi's eligibility
check APIs. Please contact Stedi customer support to enable access and add MBI
lookups to your agreement.
## Enrollment
Before you can perform MBI lookups, you must complete [transaction enrollment](/healthcare/transaction-enrollment) for [payer ID: MBILU](https://www.stedi.com/healthcare/network?page=0\&search=MBILU\&entry=ASKVB).
## Perform an MBI Lookup
You can perform MBI lookups using the following endpoints:
* [Real-Time Eligibility Check JSON](/api-reference/healthcare/post-healthcare-eligibility)
* [Real-Time Eligibility Check Raw X12](/api-reference/healthcare/post-healthcare-eligibility-raw-x12)
* [Batch Eligibility Check](/api-reference/healthcare/post-healthcare-batch-eligibility)
### Request
Construct an eligibility check request that includes the patient's first name, last name, date of birth, and Social Security Number (SSN).
Set the `tradingPartnerServiceId` to `MBILU`. This is a special payer ID that tells Stedi to perform an MBI lookup for the patient in addition to a standard eligibility check.
The following sample request performs an MBI lookup for a patient named Jane Doe.
{/* schema:EligibilityCheckRequestContent */}
```bash Example MBI Lookup request
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3 \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "MBILU",
"externalPatientId": "UAA111222333",
"encounter": {
"serviceTypeCodes": [
"30"
]
},
"provider": {
"organizationName": "ACME Health Services",
"npi": "1999999984"
},
"subscriber": {
"dateOfBirth": "19000101",
"firstName": "Jane",
"lastName": "Doe",
"ssn": "123456789"
}
}'
```
### Response
Stedi uses the patient’s demographic data and SSN to perform an MBI lookup. If there is a match, Stedi submits an eligibility check to CMS.
Stedi returns a complete eligibility response from CMS for the patient and places the patient's MBI in the `subscriber.memberId` property.
Visit [Determine patient benefits](/healthcare/eligibility-active-coverage-benefits) for details about how you can use the eligibility response to determine a patient's coverage status and benefits.
The following example shows a CMS eligibility response returned from an MBI lookup. In this scenario, the patient's MBI is `1AA2CC3DD45`.
{/* schema:EligibilityCheckResponseContent */}
```json Example MBI Lookup response
{
"meta": {
"senderId": "STEDI",
"submitterId": "117151744",
"applicationMode": "production",
"traceId": "11112222333344445555666677",
"outboundTraceId": "11112222333344445555666677"
},
"controlNumber": "112233445",
"reassociationKey": "112233445",
"tradingPartnerServiceId": "CMS",
"provider": {
"providerName": "ACME HEALTH SERVICES",
"entityIdentifier": "Provider",
"entityType": "Non-Person Entity",
"npi": "1999999984"
},
"subscriber": {
"memberId": "1AA2CC3DD45",
"firstName": "JANE",
"lastName": "DOE",
"middleName": "A",
"gender": "F",
"entityIdentifier": "Insured or Subscriber",
"entityType": "Person",
"dateOfBirth": "19000101",
"address": {
"address1": "1234 FIRST ST",
"city": "NEW YORK",
"state": "WV",
"postalCode": "123451111"
}
},
"payer": {
"entityIdentifier": "Payer",
"entityType": "Non-Person Entity",
"name": "CMS",
"payorIdentification": "CMS"
},
"planDateInformation": {
"eligibility": "20241025"
},
"planStatus": [
{
"statusCode": "1",
"status": "Active Coverage",
"serviceTypeCodes": ["88"]
},
{
"statusCode": "1",
"status": "Active Coverage",
"serviceTypeCodes": [
"30",
"42",
"45",
"48",
"49",
"69",
"76",
"83",
"A5",
"A7",
"AG",
"BT",
"BU",
"BV"
]
},
{
"statusCode": "1",
"status": "Active Coverage",
"serviceTypeCodes": [
"30",
"2",
"23",
"24",
"25",
"26",
"27",
"28",
"3",
"33",
"36",
"37",
"38",
"39",
"40",
"42",
"50",
"51",
"52",
"53",
"67",
"69",
"73",
"76",
"83",
"86",
"98",
"A4",
"A6",
"A8",
"AI",
"AJ",
"AK",
"AL",
"BT",
"BU",
"BV",
"DM",
"UC"
]
}
],
"benefitsInformation": [
{
"code": "I",
"name": "Non-Covered",
"serviceTypeCodes": ["41", "54"],
"serviceTypes": ["Routine (Preventive) Dental", "Long Term Care"],
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable"
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["88"],
"serviceTypes": ["Pharmacy"],
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable"
},
{
"code": "R",
"name": "Other or Additional Payor",
"insuranceTypeCode": "QM",
"insuranceType": "Qualified Medicare Beneficiary",
"planCoverage": "CA QMB Plan",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsDateInformation": {
"coordinationOfBenefits": "20230101"
}
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"30",
"42",
"45",
"48",
"49",
"69",
"76",
"83",
"A5",
"A7",
"AG",
"BT",
"BU",
"BV"
],
"serviceTypes": [
"Health Benefit Plan Coverage",
"Home Health Care",
"Hospice",
"Hospital - Inpatient",
"Hospital - Room and Board",
"Maternity",
"Dialysis",
"Infertility",
"Psychiatric - Room and Board",
"Psychiatric - Inpatient",
"Skilled Nursing Care",
"Gynecological",
"Obstetrical",
"Obstetrical/Gynecological"
],
"insuranceTypeCode": "MA",
"insuranceType": "Medicare Part A",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsDateInformation": {
"plan": "20190101"
},
"additionalInformation": [
{
"description": "0-Beneficiary insured due to age OASI"
}
]
},
{
"code": "C",
"name": "Deductible",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"insuranceTypeCode": "QM",
"insuranceType": "Qualified Medicare Beneficiary",
"planCoverage": "Medicare Part A",
"timeQualifierCode": "26",
"timeQualifier": "Episode",
"benefitAmount": "0",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsDateInformation": {
"plan": "20240101-20241231"
}
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"30",
"2",
"23",
"24",
"25",
"26",
"27",
"28",
"3",
"33",
"36",
"37",
"38",
"39",
"40",
"42",
"50",
"51",
"52",
"53",
"67",
"69",
"73",
"76",
"83",
"86",
"98",
"A4",
"A6",
"A8",
"AI",
"AJ",
"AK",
"AL",
"BT",
"BU",
"BV",
"DM",
"UC"
],
"serviceTypes": [
"Health Benefit Plan Coverage",
"Surgical",
"Diagnostic Dental",
"Periodontics",
"Restorative",
"Endodontics",
"Maxillofacial Prosthetics",
"Adjunctive Dental Services",
"Consultation",
"Chiropractic",
"Dental Crowns",
"Dental Accident",
"Orthodontics",
"Prosthodontics",
"Oral Surgery",
"Home Health Care",
"Hospital - Outpatient",
"Hospital - Emergency Accident",
"Hospital - Emergency Medical",
"Hospital - Ambulatory Surgical",
"Smoking Cessation",
"Maternity",
"Diagnostic Medical",
"Dialysis",
"Infertility",
"Emergency Services",
"Professional (Physician) Visit - Office",
"Psychiatric",
"Psychotherapy",
"Psychiatric - Outpatient",
"Substance Abuse",
"Alcoholism",
"Drug Addiction",
"Vision (Optometry)",
"Gynecological",
"Obstetrical",
"Obstetrical/Gynecological",
"Durable Medical Equipment",
"Urgent Care"
],
"insuranceTypeCode": "MB",
"insuranceType": "Medicare Part B",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsDateInformation": {
"plan": "20190101"
},
"additionalInformation": [
{
"description": "0-Beneficiary insured due to age OASI"
}
]
},
{
"code": "C",
"name": "Deductible",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"insuranceTypeCode": "QM",
"insuranceType": "Qualified Medicare Beneficiary",
"planCoverage": "Medicare Part B",
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "0",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsDateInformation": {
"plan": "20240101-20241231"
}
},
{
"code": "A",
"name": "Co-Insurance",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"insuranceTypeCode": "QM",
"insuranceType": "Qualified Medicare Beneficiary",
"planCoverage": "Medicare Part B",
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitPercent": "0",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsDateInformation": {
"plan": "20240101-20241231"
}
},
{
"code": "R",
"name": "Other or Additional Payor",
"serviceTypeCodes": ["88"],
"serviceTypes": ["Pharmacy"],
"insuranceTypeCode": "OT",
"insuranceType": "Other",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsAdditionalInformation": {
"planNumber": "A0505",
"planNetworkIdNumber": "555"
},
"benefitsDateInformation": {
"benefit": "20230101"
},
"benefitsRelatedEntity": {
"entityIdentifier": "Payer",
"entityType": "Non-Person Entity",
"entityName": "UHC OF CALIFORNIA",
"address": {
"address1": "202 Main St",
"city": "Sacramento",
"state": "CA",
"postalCode": "94203"
},
"contactInformation": {
"contacts": [
{
"communicationMode": "Telephone",
"communicationNumber": "8006446644"
},
{
"communicationMode": "Uniform Resource Locator (URL)",
"communicationNumber": "UHC.com/Medicare"
}
]
}
},
"benefitsRelatedEntities": [
{
"entityIdentifier": "Payer",
"entityType": "Non-Person Entity",
"entityName": "UHC OF CALIFORNIA",
"address": {
"address1": "202 Main St",
"city": "Sacramento",
"state": "CA",
"postalCode": "94203"
},
"contactInformation": {
"contacts": [
{
"communicationMode": "Telephone",
"communicationNumber": "8006446644"
},
{
"communicationMode": "Uniform Resource Locator (URL)",
"communicationNumber": "UHC.com/Medicare"
}
]
}
}
]
},
{
"code": "U",
"name": "Contact Following Entity for Eligibility or Benefit Information",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"insuranceTypeCode": "HN",
"insuranceType": "Health Maintenance Organization (HMO) - Medicare Risk",
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable",
"benefitsAdditionalInformation": {
"planNumber": "A0505",
"planNetworkIdNumber": "555"
},
"benefitsDateInformation": {
"coordinationOfBenefits": "20230101"
},
"benefitsRelatedEntity": {
"entityIdentifier": "Primary Payer",
"entityType": "Non-Person Entity",
"entityName": "UHC OF CALIFORNIA",
"address": {
"address1": "202 Main St",
"city": "Sacramento",
"state": "CA",
"postalCode": "94203"
},
"contactInformation": {
"contacts": [
{
"communicationMode": "Telephone",
"communicationNumber": "8006446644"
},
{
"communicationMode": "Uniform Resource Locator (URL)",
"communicationNumber": "UHC.com/Medicare"
}
]
}
},
"benefitsRelatedEntities": [
{
"entityIdentifier": "Primary Payer",
"entityType": "Non-Person Entity",
"entityName": "UHC OF CALIFORNIA",
"address": {
"address1": "202 Main St",
"city": "Sacramento",
"state": "CA",
"postalCode": "94203"
},
"contactInformation": {
"contacts": [
{
"communicationMode": "Telephone",
"communicationNumber": "8006446644"
},
{
"communicationMode": "Uniform Resource Locator (URL)",
"communicationNumber": "UHC.com/Medicare"
}
]
}
}
],
"additionalInformation": [
{
"description": "MA Bill Option Code - A"
}
]
}
],
"errors": [],
"x12": ""
}
```
### Concurrency limit
MBI lookups you perform using real-time eligibility check endpoints (JSON and Raw X12) share a concurrency pool with other real-time healthcare APIs. For more information, visit [Concurrency limits](/api-reference#concurrency-limits).
MBI lookups you perform using the [Batch Eligibility Check](/api-reference/healthcare/post-healthcare-batch-eligibility) endpoint don't count toward your Stedi account concurrency limit.
## Mock request
When you submit the following mock MBI lookup request to the [Real-Time Eligibility Check](/api-reference/healthcare/post-healthcare-eligibility) endpoint with a [test API key](/api-reference#api-key-types), Stedi returns mock benefits data you can use for testing.
Mock requests are free for testing purposes and won't incur any charges in
your Stedi account.
Request Notes:
* `encounter`: Only service type code 30 is supported.
* `provider`: You can use any organization name and any NPI, as long as it passes check digit validation. To generate a dummy NPI, you can use this [free tool](https://jsfiddle.net/alexdresko/cLNB6).
* `subscriber`: You must use the exact values in the test request. Other birth dates, first names, last names, and Social Security Numbers return errors.
{/* schema:EligibilityCheckRequestContent */}
```bash
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key ' \
--header 'Content-Type: application/json' \
--data '{
"controlNumber": "112233445",
"tradingPartnerServiceId": "MBILU",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"lastName": "Doe",
"dateOfBirth": "19550505",
"ssn": "123456789"
},
"encounter": {
"serviceTypeCodes": [
"30"
]
}
}'
```
## Health Insurance Claim Number (HICN)
Some payers return the patient's MBI in one of the following properties of the standard eligibility response:
* [`benefitsInformation.benefitsAdditionalInformation.hicNumber`](/api-reference/healthcare/post-healthcare-eligibility#response.benefitsInformation.benefitsAdditionalInformation.hicNumber)
* [`planInformation.hicNumber`](/api-reference/healthcare/post-healthcare-eligibility#response.planInformation.hicNumber)
If the value in either of these properties matches the format specified in the [Medicare Beneficiary Identifier documentation](https://www.cms.gov/training-education/partner-outreach-resources/new-medicare-card/medical-beneficiary-identifiers-mbis), the number is likely an MBI. In these cases, you don't need to perform an MBI lookup - you can use this value in a standard eligibility check to CMS.
You're most likely to receive an MBI in eligibility responses from commercial Medicare Advantage plans, but they can also be present in responses from Medicaid plans for dual-eligible patients.
## Medicare Advantage plans
A Medicare Advantage plan (also known as Medicare Part C) is a type of health insurance plan offered by private companies that contract with Medicare to provide all of a patient's Part A (hospital insurance) and Part B (medical insurance) benefits.
Medicare Advantage plans have their own unique member ID, which **isn't** returned in the MBI lookup response. You also shouldn't submit eligibility checks for Medicare Advantage plans to CMS (HETS) - you should submit them to the actual Medicare Advantage plan payer instead.
However, you can use MBI lookups to determine a patient's Medicare Advantage payer. If available, the MBI lookup response will include the patient's Medicare Advantage plan name in the [`benefitsInformation.benefitsRelatedEntities.entityName`](/api-reference/healthcare/post-healthcare-eligibility#response.benefitsInformation.benefitsRelatedEntities.entityName) property.
Many Medicare Advantage plans allow you to submit [eligibility checks](/healthcare/send-eligibility-checks) with just the patient's name and date of birth. However, if that approach is unsuccessful and you don't have the patient's member ID, you can use [Insurance Discovery](/healthcare/insurance-discovery) to retrieve benefits information with the patient's demographic information instead.
## Recommended retry strategy
Implementing the right retry strategy for eligibility check failures saves a lot of time and money.
At a minimum, we **strongly recommend** automatically retrying every request that fails due to payer connectivity issues. Automatic retries resolve a significant portion of these types of failures without manual intervention. Visit [Retry strategy](/healthcare/eligibility-troubleshooting#retry-strategy) for details.
# Model Context Protocol (MCP)
Source: https://www.stedi.com/docs/healthcare/mcp-server
***
title: Model Context Protocol (MCP)
sidebarTitle: "Model Context Protocol (MCP)"
--------------------------------------------
Our Model Context Protocol (MCP) server defines a set of tools that AI agents can use to perform and troubleshoot eligibility checks through Stedi.
When building agents that work with eligibility data, we recommend using our MCP server. It excels at individual eligibility checks, especially when your agent needs to retrieve coverage data in real time. For example:
* A voice agent can use the MCP server to quickly verify benefits in a few seconds instead of calling payers over the phone. It can then place follow-up calls to payers only as needed - for example, to collect additional benefit details.
* A Revenue Cycle Management (RCM) workflow agent can use the MCP server to validate a patient's coverage before scheduling an appointment or submitting a claim.
You can also use the MCP server to perform individual checks with MCP clients. This is useful for testing your integration during development and for enabling operations teams to run ad-hoc checks or troubleshoot issues. Be sure to put measures in place to stay compliant with your organization's data-handling policies, HIPAA, and other applicable requirements.
## Why use the MCP server?
Performing eligibility checks successfully requires more than just calling Stedi's APIs. In addition to determining the right payer, you must know the required and recommended properties, know how to interpret errors, and build out a robust retry strategy for various failure cases.
The troubleshooting process can be complex. For example, if your check fails due to a payer connectivity issue, you should retry immediately. If it fails due to a `Subscriber Not Found` error, you must systematically diagnose the issue in order to successfully retrieve benefits information. We have best practices for entering [patient data](/healthcare/send-eligibility-checks#patient-information), [troubleshooting](/healthcare/eligibility-troubleshooting), and [retries](/healthcare/eligibility-troubleshooting#retry-strategy) in our docs - you'd typically need to implement this logic in your product and then maintain it over time.
The MCP server is helpful because it comes with all of this logic built in. Specifically, it allows agents to:
* **Find the correct payer:** The MCP server has a tool for searching Stedi's payer database. This allows agents to access information like payer IDs and supported transaction types as needed when answering questions or running eligibility checks.
* **Run eligibility checks:** The MCP server has a tool for constructing and submitting eligibility requests using available patient and provider data. If the first attempt fails, the server provides instructions about how to adjust inputs, retry, and move forward.
* **Troubleshoot rejection codes:** The MCP server provides instructions on what to do in these scenarios – for example, remove the member ID, adjust the name, or try alternate, related payer IDs. These are the same tactics our support team uses internally to resolve issues.
In essence, the MCP server allows you to tell your agent to "run an eligibility check" at the appropriate times during its workflow. You can focus on building your agent's core functionality, while the MCP server handles the complexities of eligibility checks.
### Limitations
The MCP server is designed for an agent that is performing and troubleshooting a single eligibility check. It's not intended for bulk eligibility checks, or for interpreting the benefits in an eligibility response.
* For bulk eligibility checks, use Batch Eligibility Check API directly. Visit [batch refresh checks](/healthcare/batch-refresh-eligibility-checks) for details.
* To interpret the eligibility response, you'll need to layer your own logic on top of the MCP server. For example, you'll need custom logic for tasks like determining whether a patient has active coverage for a particular service or retrieving the patient's copay. Visit [determine patient benefits](/healthcare/eligibility-active-coverage-benefits) for complete details.
### Data security and compliance
The MCP server uses the same security model as our existing APIs, including TLS encryption and API key authentication.
If you're using our MCP server with a third-party tool like Claude or ChatGPT, follow your organization's data handling policies to ensure that you stay compliant with HIPAA and other applicable requirements. For example, your organization likely requires a BAA with any third-party tool before using the tool with Stedi's MCP server.
## How the MCP server works
Your AI agent connects to the server using an MCP client. Once connected, the server gives your agent access to the available [tools](#tools) and [prompts](#prompts) for running eligibility checks.

The MCP server adds minimal overhead - you'll get the same fast response times from our APIs with added intelligence for your agents.
### Tools
Tools interact with Stedi's APIs to perform tasks. The MCP server provides the following tools for your agent to use:
| Tool Name | Description |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `search_for_payer` | Calls the [Search Payers](/api-reference/healthcare/get-search-payers) endpoint to find a Stedi payer based on a provided payer ID or name. It even works with partial names or typos. For example, `cig` finds Cigna. |
| `eligibility_check` | Runs an eligibility check using the [Real-Time Eligibility Check JSON](/api-reference/healthcare/post-healthcare-eligibility) endpoint. The JSON format provides the most reliable results for AI agents. |
### Prompts
The MCP server includes prompts to help your agent recover from common eligibility errors. They cover the most common recoverable scenarios we see in production:
* How to handle common errors
* When to retry eligibility checks
* What to do when a payer isn't found
You and your agent stay in control of executing follow-up actions, such as troubleshooting and retries.
Many LLM clients don't automatically read prompt definitions. You must explicitly instruct them to “read the prompts” or use a client-specific command. Otherwise, the model may never access prompt content.
## Install the MCP server
The eligibility MCP server is a Streamable HTTP MCP server hosted at [https://mcp.us.stedi.com/2025-07-11/mcp](https://mcp.us.stedi.com/2025-07-11/mcp).
To connect your agent:
* Create a [production API key](/api-reference#api-key-types) for authentication.
* Add the following configuration to your agent's MCP client:
```json
{
"mcpServers": {
"stedi-healthcare": {
"type": "http",
"url": "https://mcp.us.stedi.com/2025-07-11/mcp",
"headers": {
"Authorization": "STEDI_PROD_API_KEY"
}
}
}
}
```
## Example use
Here are some examples of how you might use the MCP server in different scenarios.
### Voice agent workflow
You can instruct your agent to use the MCP server to run eligibility checks. For example, you might give your voice agent the following prompt:
```
Read the prompts from Stedi's MCP server.
Then use Stedi's MCP server to check the patient's eligibility programmatically before making a phone call to the payer.
```
### RCM agent workflow
You can instruct your agent to use the MCP server to check patient eligibility before scheduling appointments. For example, you could give it the following prompt:
```
Read the prompts from Stedi's MCP server.
Then use Stedi's MCP server to check the patient's eligibility programmatically before scheduling an appointment.
```
### Payer search
You can use the MCP server directly in an MCP client to retrieve payer information. For example, after connecting the MCP server, you could give the client the following prompt:
```
Does Cigna support eligibility checks?
```
## Pricing
The MCP server is available on all [paid Stedi plans](https://www.stedi.com/pricing). There is no charge for using the MCP server itself - you'll only be charged for related API requests.
Note that for eligibility checks, there's no charge for non-billable requests, such as those that return errors indicating that the payer is down. Visit [billing for eligibility checks](/healthcare/intro-eligibility-checks#billing-for-eligibility-checks) for details.
# National Provider Identifier (NPI)
Source: https://www.stedi.com/docs/healthcare/national-provider-identifier
***
title: National Provider Identifier (NPI)
sidebarTitle: "National Provider Identifiers"
---------------------------------------------
The National Provider Identifier (NPI) is a unique identification number assigned to healthcare providers. It’s used to identify providers in healthcare transactions, like billing, referrals, and insurance claims, and it's required when processing administrative and financial transactions adopted under HIPAA (the Health Insurance Portability and Accountability Act).
If a provider has an NPI, it's required when completing [transaction enrollment](/healthcare/transaction-enrollment) and when sending any healthcare transaction through Stedi, including eligibility checks and claims. In certain rare circumstances, payers may allow providers who don't have an NPI to submit transactions using another identifier, such as their Social Security Number (SSN) instead. Providers who don't have an NPI are typically non-medical providers, such as social workers, home health aides, or transportation services.
In practice, alternative identifiers to the NPI are almost never supported, and using alternative identifiers typically requires a special agreement with the payer. We don't recommend attempting to send an alternative identifier in any transaction unless the payer has explicitly instructed you to do so.
## NPI types
There are two types of NPIs:
* **Type 1 - Individual:** This type of NPI is for individual healthcare providers, such as doctors, dentists, nurse practitioners, physical therapists, and chiropractors. Note that providers who run their own practice likely still need to obtain an individual NPI to use when billing services under their own name.
* **Type 2 - Organization:** This type of NPI is for healthcare organizations or group practices, such as hospitals, clinics, labs, nursing homes, and home health agencies. This type of NPI is used when billing services under the organization’s name, not an individual person. Unlike individual NPIs, a single organization can have multiple organization NPIs for different locations, divisions, or services.
## Find a provider's NPI
You can look up a provider's NPI using the [NPPES NPI Registry](https://npiregistry.cms.hhs.gov/search). The registry allows you to search for NPIs by name, organization, or NPI number. You can also verify the status of an NPI and view the provider's information, including their taxonomy codes and practice locations.
## Generate a dummy NPI
You can generate a dummy NPI for test transactions using this [free online tool](https://jsfiddle.net/alexdresko/cLNB6). Note that these dummy NPIs aren't valid for production transactions.
## Apply for an NPI
You can obtain an NPI from the [National Plan and Provider Enumeration System (NPPES)](https://nppes.cms.hhs.gov/webhelp/nppeshelp/NPPES%20FAQS.html#how-do-i-apply-for-an-npi). The process includes the following steps:
You'll be required to provide the following in your application:
* Personal information, such as your name, address, and phone number
* Type of provider (individual or organization)
* Provider specialty (taxonomy code)
* Practice location and contact information
* Other information, such as your state license number and the name of your state licensing board
Most online applications are processed within 10 business days; paper applications may take longer. Once approved, you'll receive your 10-digit NPI number through email or mail, depending on how you applied.
## NPI format and validation
The NPI is a 10-position, intelligence-free numeric identifier (10-digit number). This means that the numbers do not carry other information about healthcare providers, such as the state in which they live or their medical specialty.
The NPI format consists of 9 numeric digits followed by one numeric check digit. The check digit is calculated using the Luhn formula. When you submit a transaction such as an eligibility check or claim to Stedi, we validate the NPI before submitting it to the upstream payer. At a minimum, we validate that the submitted number passes check digit validation. For example, NPIs in test eligibility checks submitted with a test API key must pass check digit validation. In certain cases, we also validate that the NPI exists in the NPPES database.
### Calculate the check digit manually
Assume the 9-position identifier part of the NPI is 123456789. Using the Luhn formula on the identifier portion, you would calculate the check digit as follows:
1. Double the value of alternate digits, beginning with the rightmost digit:
2 6 10 14 18
2. Add a constant 24 (to account for the 80840 prefix that would be present on a card issuer identifier), plus the individual digits of the products of doubling, plus unaffected digits:
24 + 2 + 2 + 6 + 4 + 1 + 0 + 6 + 1 + 4 + 8 + 1 + 8 = 67
3. Subtract the sum from the next higher number ending in zero:
70 - 67 = 3
The check digit is 3. So, the final NPI with check digit is 1234567893.
# Get and correlate acknowledgments and ERAs
Source: https://www.stedi.com/docs/healthcare/receive-claim-responses
***
title: 'Get and correlate acknowledgments and ERAs'
sidebarTitle: 'Get and correlate acknowledgments and ERAs'
----------------------------------------------------------
After you submit a professional, dental, or institutional claim, you may receive asynchronous 277CA claim acknowledgment and 835 Electronic Remittance Advice (ERA) responses.
If you submitted the claims through the API or UI, there are two steps to retrieve claim responses from Stedi:
1. Discover responses by polling for processed transactions or listening for event-driven webhooks.
2. Call Stedi APIs to retrieve processed responses from Stedi.
Once you have the responses, you can correlate them with the original claim and specific service lines.
If you're using a [Stedi SFTP connection](/healthcare/submit-claims-sftp-connection), you don't need to poll or call Stedi APIs to retrieve responses. Instead, you can download them from the `from-stedi` directory.
## Response types
You can receive two types of responses after you submit a professional, institutional, or dental claim.
### 277CA claim acknowledgment
The 277CA indicates whether the claim was accepted or rejected and (if relevant) the reasons for rejection. Though it can contain claim status information, the 277CA is different from the synchronous 277 claim status response you receive after submitting a [real-time claim status](/api-reference/healthcare/post-healthcare-claim-status) request.
You may receive multiple separate 277CAs for each claim you submit.
* You'll receive the first 277CA from Stedi within about 30 minutes of submitting the claim. This 277CA may contain rejection message(s) and warnings, if applicable.
* You may receive additional 277CAs from intermediary clearinghouses.
* You'll receive one or more 277CAs from the payer. Typically, there is one 277CA that indicates receipt of the claim and a second 277CA that contains summary counts of transactions received, information about accepted transactions, and details for rejected transactions.
Each 277CA typically correlates to one 837 claim. However, some payers may send a single 277CA that [references multiple claims](/healthcare/receive-claim-responses#correlate-277ca).
#### Determine sender
You can determine whether a 277CA is from a clearinghouse or the payer from the [`transactions.payers` array](https://www.stedi.com/docs/api-reference/healthcare/get-healthcare-reports-277#response-transactions-payers) in the report. The `organizationName` property contains the name of the sender (for example, `CIGNA`) and the `identityIdentifierCodeValue` contains either `Clearinghouse` or `Payer`.
This information is also available at the top of the 277CA's [transaction details page](https://portal.stedi.com/app/core/transactions) in the Stedi portal.
### 835 Electronic Remittance Advice (ERA)
The ERA contains details about payments for specific services and explanations for any adjustments or denials. The payer only sends ERAs for accepted claims. If a claim is rejected in a 277CA, there's no adjudication or payment information to report.
Processing ERAs always requires [transaction enrollment](/healthcare/transaction-enrollment) with the payer.
#### Duplicate ERAs
Payers typically only send one ERA per claim. However, they may occasionally retransmit another identical 835 ERA, so you should have logic in place to handle these duplicates.
You can assume an ERA is a duplicate if the Check or EFT Trace Number is the same. This is the `transactions[].paymentAndRemitReassociationDetails.checkOrEFTTraceNumber` property in a processed 835 ERA from Stedi. In X12 EDI, this is available in segment `TRN` (Reassociation Trace Number), element `TRN02` (Check or EFT Trace Number).
### 277CA claim status details
The 277CA response contains two main objects for claim status information:
* `informationClaimStatuses`: This is the primary section to examine for detailed acceptance/rejection status of a claim. It contains information that would be useful to the submitter of the claim regarding acceptance/rejection, including:
* Payer-specific rejection reasons
* Claim charge amount details
* The `patientControlNumber` from the claim (returned as `patientAccountNumber`)
* All granular claim processing details
* `providerClaimStatuses`: This section contains more generic information that would be useful to the provider regarding rejection/acceptance. It typically only includes basic status information like "accepted for processing" or "denied" without the granular information in `informationClaimStatuses`.
## Discover processed responses
You can discover processed responses by either listening for webhooks or polling for transactions.
### Listen for webhooks
Instead of polling for transactions, you can set up [webhooks](/healthcare/configure-webhooks) that automatically send events for processed 277CAs and 835 ERAs to your endpoint. You can either create a single webhook for all inbound transactions or create a separate webhook for each transaction type.
These webhooks are triggered by the processing events Stedi emits after it successfully receives and processes a response from the payer or intermediary clearinghouse.
```json tab="processed 277CA"
{
"event": {
"version": "0",
"id": "f972fb53-653a-1747-ce30-bed15fc04f5c",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2024-07-18T16:21:24Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/transactions/f0d3f790-0bc9-432b-93kd-e4b7ece67946"
],
"detail": {
"transactionId": "f0d4f780-0ec9-432b-93gd-e4b7ece93946",
"direction": "INBOUND",
"mode": "test",
"fileExecutionId": "9f76b485-6hca-43bf-917e-d5b54bec6234",
"processedAt": "2024-07-18T16:21:24.658Z",
"fragments": null,
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"url": "https://core.us.stedi.com/2023-08-01/transactions/f0d9f790-0ec9-431b-93fd-e4h7ece63946/input",
"sizeBytes": 1313,
"model": "transaction"
},
{
"artifactType": "application/json",
"usage": "output",
"url": "https://core.us.stedi.com/2023-08-01/transactions/f0d3f740-0ec9-432b-98fd-e4b7ece63946/output",
"sizeBytes": 5602,
"model": "transaction"
}
],
"partnership": {
"partnershipId": "local-clearinghouse-test",
"partnershipType": "x12",
"sender": {
"profileId": "clearinghouse-test"
},
"receiver": {
"profileId": "local"
}
},
"x12": {
"transactionSetting": {
"guideId": "01J1M50C1Q44KYDZY8V7R1TPBW",
"transactionSettingId": "01J1M50P9623BFE0FFT5Q2BR49"
},
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "0",
"controlNumber": 11
},
"functionalGroup": {
"controlNumber": 11,
"release": "005010X214",
"date": "2024-07-18",
"time": "16:20:47",
"functionalIdentifierCode": "HN"
},
"transaction": {
"controlNumber": "1001",
"transactionSetIdentifier": "277"
},
"receiver": {
"applicationCode": "001690149382",
"isa": {
"qualifier": "ZZ",
"id": "001690149382"
}
},
"sender": {
"applicationCode": "STEDITEST",
"isa": {
"qualifier": "ZZ",
"id": "STEDITEST"
}
}
}
},
"connectionId": "01J1M5124B2HWMNN91Q3Z6AM61"
}
}
}
```
```json tab="processed 835 ERA"
{
"event": {
"version": "0",
"id": "5d1bcb90-cb0b-1844-5b93-86d5e5b9c4a8",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2025-07-14T20:43:39Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/transactions/95e7786c-7066-4494-b83a-b1f300624902"
],
"detail": {
"transactionId": "95e7786c-7066-4494-b83a-b1f300624902",
"direction": "INBOUND",
"mode": "test",
"fileExecutionId": "5d30f0a0-63af-4aeb-b96c-353b4b25c99a",
"processedAt": "2025-07-14T20:43:39.808Z",
"fragments": null,
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"url": "https://core.us.stedi.com/2023-08-01/transactions/95e7786c-7066-4494-b83a-b1f300624902/input",
"sizeBytes": 2016,
"model": "transaction"
},
{
"artifactType": "application/json",
"usage": "output",
"url": "https://core.us.stedi.com/2023-08-01/transactions/95e7786c-7066-4494-b83a-b1f300624902/output",
"sizeBytes": 13864,
"model": "transaction"
}
],
"partnership": {
"partnershipId": "local-clearinghouse-test",
"partnershipType": "x12",
"sender": {
"profileId": "clearinghouse-test"
},
"receiver": {
"profileId": "local"
}
},
"x12": {
"transactionSetting": {
"guideId": "01J8JH1SGTB2FYKN2PG4MH84RP",
"transactionSettingId": "01J8JH23VA3G2X8GENVVE6XZB9"
},
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "0",
"controlNumber": 1
},
"functionalGroup": {
"controlNumber": 1,
"release": "005010X221A1",
"date": "2025-07-14",
"time": "20:43:21",
"functionalIdentifierCode": "HP"
},
"transaction": {
"controlNumber": "0001",
"transactionSetIdentifier": "835"
},
"receiver": {
"applicationCode": "599264680681",
"isa": {
"qualifier": "ZZ",
"id": "599264680681"
}
},
"sender": {
"applicationCode": "STEDITEST",
"isa": {
"qualifier": "ZZ",
"id": "STEDITEST"
}
}
}
},
"connectionId": "01JE9257XJ4G4YFMXCHJPFR434"
}
}
}
```
As these events are emitted, you can:
* Determine the transaction type from the `x12.transactionSetIdentifier` property: `277` (277CA) or `835` (ERA).
* Use either the `transactionId` to retrieve the transaction in JSON format or the `fileExecutionId` to retrieve the transaction in X12 EDI format. Visit [Retrieve responses from Stedi](#retrieve-responses-from-stedi) for more information.
If your webhook doesn't respond within 5 seconds, Stedi marks that as a failure and then automatically retries up to 5 times. This can result in duplicate deliveries, so we strongly recommend implementing ways to manage duplicates delivered through webhooks.
### Poll for transactions
Call the [Poll Transactions](/api-reference/edi-platform/core/get-pollingtransactions) endpoint to return a list of transactions in your Stedi account.
You must include the following information in the request:
* Your Stedi API key as the `Authorization` header.
* Either the `startDateTime` or `pageToken` query parameters. To retrieve a list of transactions after a specific date, use `startDateTime`. To retrieve the next page of transactions, use `pageToken` (you can find this value in the `nextPageToken` field in the response).
The following example shows an API call to retrieve transactions after a specific date:
```bash
curl --request GET -L \
--url https://core.us.stedi.com/2023-08-01/polling/transactions?startDateTime=2023-08-28T00:00:00Z \
--header "Authorization: ${STEDI_API_KEY}"
```
**Filter for 277CA and 835 ERA transactions**
The response includes all transactions that have been sent or received, including all 837 claims you have submitted and all 277CA and 835 ERA responses you have received from payers. You must filter for transactions that match the following criteria:
* `direction`: `INBOUND` - This indicates that the transaction came from the payer or intermediary clearinghouse.
* `x12.transactionSetIdentifier`: `277` or `835`
The following example shows a response containing a processed 277CA transaction:
```json
{
"items": [
{
"direction": "INBOUND",
"mode": "production",
"fileExecutionId": "f75168e4-e682-4410-bfec-b5b1541c7f21",
"transactionId": "a15b68ca-fae0-42de-b8a3-f436668b8604",
"processedAt": "2023-08-28T09:00:28.354Z",
"artifacts": [
{
"artifactType": "application/edi-x12",
"sizeBytes": 490,
"usage": "input",
"url": "https://core.us.stedi.com/2023-08-01/transactions/a15b68ca-fae0-42de-b8a3-f436668b8604/input"
},
{
"artifactType": "application/json",
"sizeBytes": 51,
"usage": "output",
"url": "https://core.us.stedi.com/2023-08-01/transactions/a15b68ca-fae0-42de-b8a3-f436668b8604/output"
}
],
"partnership": {
"partnershipId": "customer_availity",
"partnershipType": "x12",
"sender": {
"profileId": "availity_sender"
},
"receiver": {
"profileId": "availity_receiver"
}
},
"x12": {
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "0",
"controlNumber": 2
},
"functionalGroup": {
"controlNumber": 2,
"release": "008010",
"date": "2023-08-28",
"time": "09:00:20",
"functionalIdentifierCode": "HN"
},
"transaction": {
"controlNumber": "1",
"transactionSetIdentifier": "277"
},
"receiver": {
"applicationCode": "AV01101957",
"isa": {
"qualifier": "ZZ",
"id": "AV01101957"
}
},
"sender": {
"applicationCode": "030240928",
"isa": {
"qualifier": "01",
"id": "030240928"
}
}
},
"transactionSetting": {
"guideId": "01H8PSWG4ZD6QPKC9VSD42PQX3",
"transactionSettingId": "01H8PSWG4ZD6QPKC9VSD42PQX3"
}
}
}
],
"nextPageToken": "945ff6de213d3ef481d028065d4c12fb996a166a3a90ef98564318decfae50ce4b36d74b7e9d9bafa6e1d169"
}
```
For each matching transaction, extract the `x12.transactionSetIdentifier` type and either the `transactionId` or the `fileExecutionId` to use when mapping the data. You'll use the `transactionId` to retrieve the transaction in JSON format or the `fileExecutionId` to retrieve the transaction in X12 EDI format. Visit [Retrieve responses from Stedi](#retrieve-responses-from-stedi) for more information.
Stedi does not allow you to delete transactions, so make sure you track which transaction and/or file execution IDs you've already processed.
## Retrieve responses from Stedi
You can retrieve the 277CA and 835 ERA responses from Stedi in either JSON format or X12 EDI format.
### JSON format
Follow these steps to retrieve responses in JSON format:
1. Either [set up webhooks](/healthcare/receive-claim-responses#listen-for-webhooks) to listen for transaction processed events or [poll for transactions](/healthcare/receive-claim-responses#poll-for-transactions). This step allows you to discover when a new 277CA or 835 ERA is ready for retrieval.
2. Retrieve the transaction ID from the configured webhook or the Poll Transactions response. This value is available in the `transactionId` property.
3. Call the following endpoints to retrieve 277CA and 835 ERA responses from Stedi. In each request, you must include your Stedi API key in the `Authorization` header and the `transactionId` query parameter containing the ID of the transaction you want to retrieve.
* [Get 277CA Report](/api-reference/healthcare/get-healthcare-reports-277): Retrieve 277CA responses
* [Get 835 ERA Report](/api-reference/healthcare/get-healthcare-reports-835): Retrieve 835 ERA responses
### X12 EDI format
Follow these steps to retrieve the responses in X12 EDI format:
1. Either [set up webhooks](/healthcare/receive-claim-responses#listen-for-webhooks) to listen for transaction processed events or [poll for transactions](/healthcare/receive-claim-responses#poll-for-transactions). This step allows you to discover when a new 277CA or 835 ERA is ready for retrieval.
2. Retrieve the file execution ID from the configured webhook or the Poll Transactions response. This value is available in the `fileExecutionId` property.
3. Call the [Get Execution Input](/api-reference/edi-platform/core/get-executions-input) endpoint to retrieve the 277CA or 835 ERA in X12 EDI format. In the request, you must include your Stedi API key in the `Authorization` header and the `executionId` query parameter containing the file execution ID for the response you want to retrieve.
## Correlate 277CA
Use the following properties to correlate the 277CA with the original claim.
### Entire Claim
Use the claim's `claimInformation.patientControlNumber`.
It's returned in two locations in the 277CA's `transactions.payers.claimStatusTransactions.claimStatusDetails.patientClaimStatusDetails.claims.claimStatus` object:
* `patientAccountNumber`
* `referencedTransactionTraceNumber`
You can use either of these properties to correlate the 277CA with the original claim, but we recommend using the `referencedTransactionTraceNumber`.
Some payers batch acknowledgments for multiple claims into a single 277CA. In these cases, the 277CA will contain multiple `patientClaimStatusDetails` objects, each with its own `referencedTransactionTraceNumber`.
### Service line
Different claim types use different names for the same identifier:
* For professional and dental claims, use `claimInformation.serviceLines.providerControlNumber`.
* For institutional claims, use `claimInformation.serviceLines.lineItemControlNumber`.
This identifier is **sometimes** returned as the `transactions.payers.claimStatusTransactions.claimStatusDetails.patientClaimStatusDetails.claims.serviceLines.lineItemControlNumber` in the 277CA. It's not always present because a 277CA only contains a `serviceLines` object when the claim was rejected because of issues with the information provided for the service line.
The following example shows a `serviceLines` object for a rejected claim containing the `lineItemControlNumber` property.
{/* schema:ClaimAcknowledgmentServiceLines:unwrapArray */}
```json
"serviceLines": [
{
"beginServiceLineDate": "20250101",
"lineItemControlNumber": "ABCD1234",
"service": {
"chargeAmount": "379.39",
"procedureCode": "97153",
"serviceIdQualifierCode": "HC",
"serviceIdQualifierCodeValue": "Health Care Financing Administration Common Procedural Coding System (HCPCS) Codes",
"submittedUnits": "11"
},
"serviceClaimStatuses": [
{
"serviceStatuses": [
{
"entityIdentifierCode": "IL",
"entityIdentifierCodeValue": "Insured or Subscriber",
"healthCareClaimStatusCategoryCode": "A3",
"healthCareClaimStatusCategoryCodeValue": "Acknowledgement/Returned as unprocessable claim - The claim/encounter has been rejected and has not been entered into the adjudication system.",
"statusCode": "164",
"statusCodeValue": "Entity's contract/member number."
}
]
}
]
}
]
```
## Correlate 835 ERA
Use the following properties to correlate the 835 ERA with the original claim.
Sometimes, payers send [duplicate ERAs](#duplicate-eras) for the same claim. You should have logic in place to identify and manage these duplicates.
### Entire claim
Use the claim's `claimInformation.patientControlNumber`. It's returned as the `transactions.detailInfo.paymentInfo.claimPaymentInfo.patientControlNumber` in the 835 ERA.
### Service line
Different claim types use different names for the same identifier:
* For professional and dental claims, use `claimInformation.serviceLines.providerControlNumber`.
* For institutional claims, use `claimInformation.serviceLines.lineItemControlNumber`.
This identifier is always returned as the `transactions.detailInfo.paymentInfo.serviceLines.lineItemControlNumber` in the 835 ERA.
{/* schema:ClaimPaymentAdviceServiceLines:unwrapArray */}
```json
"serviceLines": [
{
"lineItemControlNumber": "111222333",
"serviceAdjustments": [
{
"adjustmentAmount1": "300",
"adjustmentReasonCode1": "1",
"claimAdjustmentGroupCode": "PR",
"claimAdjustmentGroupCodeValue": "Patient Responsibility"
}
],
"serviceDate": "20190301",
"servicePaymentInformation": {
"adjudicatedProcedureCode": "99211",
"lineItemChargeAmount": "800",
"lineItemProviderPaymentAmount": "500",
"productOrServiceIDQualifier": "HC",
"productOrServiceIDQualifierValue": "Health Care Financing Administration Common Procedural Coding System (HCPCS) Codes"
},
"serviceSupplementalAmounts": {
"allowedActual": "800"
}
}
]
```
## Crossover claims
A claim is called a crossover claim when it is adjudicated by one payer and then forwarded to another payer for additional processing. This is common in coordination of benefits (COB) situations, where a patient has multiple insurance policies. For example, a patient may have coverage through both Medicare and private supplemental insurance. Once Medicare adjudicates the claim, it "crosses over" electronically to the secondary payer. This process helps reduce paperwork for providers and ensures the patient is billed correctly for any remaining balance.
You'll know a claim has been sent to a crossover payer when you receive an 835 ERA with the [`transactions.detailInfo.paymentInfo.claimPaymentInfo.claimStatusCode`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.claimPaymentInfo.claimStatusCode) property set to either `19`, `20`, or `21`. The ERA should also include information about the crossover payer in the [`transactions.detailInfo.paymentInfo.crossoverCarrier`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.crossoverCarrier) object.
Sometimes, the different payers are separate legal entities within the same parent corporation. If not, you'll need to [enroll](/healthcare/transaction-enrollment) the provider separately with the crossover payer before they can process the claim. The payer may pause claim processing until the enrollment is complete or reject the claim. If the claim is rejected, you'll need to manually resubmit it once the enrollment is live. [Stedi support](https://www.stedi.com/contact) can help you determine when you need to enroll with a crossover payer and determine the status of crossover claims while the enrollment is in progress.
You may receive an additional 835 ERA and/or 277CAs from the crossover payer. You may also be able to use the information from any 277CAs to submit real-time claim status requests for the crossover claim.
## 277CA code lists
You may need to refer to the following code lists while evaluating the 277CA. Note that this page doesn't list all possible code lists, only those that are too long to properly represent within the API documentation.
### Claim Status Category Code
A claim’s status is reported using a category code, which is returned in multiple locations within the 277CA. For each instance, Stedi returns two properties:
* `healthCareClaimStatusCategoryCode`: The code, such as `A1`, `P2`, or `F1`.
* `healthCareClaimStatusCategoryCodeValue`: The description associated with that code.
These values indicate the status of a claim or encounter.
* `A0` - Acknowledgement/Forwarded - The claim/encounter has been forwarded to another entity.
* `A1` - Acknowledgement/Receipt - The claim/encounter has been received. This does not mean that the claim has been accepted for adjudication.
* `A2` - Acknowledgement/Acceptance into adjudication system - The claim/encounter has been accepted into the adjudication system.
* `A3` - Acknowledgement/Returned as unprocessable claim - The claim/encounter has been rejected and has not been entered into the adjudication system.
* `A4` - Acknowledgement/Not Found - The claim/encounter can not be found in the adjudication system.
* `A5` - Acknowledgement/Split Claim - The claim/encounter has been split upon acceptance into the adjudication system.
* `A6` - Acknowledgement/Rejected for Missing Information - The claim/encounter is missing the information specified in the Status details and has been rejected.
* `A7` - Acknowledgement/Rejected for Invalid Information - The claim/encounter has invalid information as specified in the Status details and has been rejected.
* `A8` - Acknowledgement/Rejected for relational field in error.
* `DR01` - Acknowledgement/Receipt - The claim/encounter has been received. This does not mean the claim has been accepted into the data reporting/processing system.
* `DR02` - Acknowledgement/Acceptance into the data reporting/processing system - The claim/encounter has been accepted into the data reporting/processing system.
* `DR03` - Acknowledgement/Returned as unprocessable claim - The claim/encounter has been rejected and has not been entered into the data reporting/processing system.
* `DR04` - Acknowledgement/Not Found - The claim/encounter can not be found in the data reporting/processing system.
* `DR05` - Acknowledgement/Rejected for Missing Information - The claim/encounter is missing the information specified in the Status details and has been rejected.
* `DR06` - Acknowledgment/Rejected for invalid information - The claim/encounter has invalid information as specified in the Status details and has been rejected.
* `DR07` - Acknowledgement/Rejected for relational field in error.
* `DR08` - Acknowledgement/Warning - The claim/encounter has been accepted into the data reporting/processing system but has received a warning as specified in the Status details.
* `P0` - Pending: Adjudication/Details - This is a generic message about a pended claim. A pended claim is one for which no remittance advice has been issued,or only part of the claim has been paid.
* `P1` - Pending/In Process - The claim or encounter is in the adjudication system.
* `P2` - Pending/Payer Review - The claim/encounter is suspended and is pending review (e.g. medical review,repricing,Third Party Administrator processing).
* `P3` - Pending/Provider Requested Information - The claim or encounter is waiting for information that has already been requested from the provider.
* `P4` - Pending/Patient Requested Information - The claim or encounter is waiting for information that has already been requested from the patient.
* `P5` - Pending/Payer Administrative/System hold
* `F0` - Finalized - The claim/encounter has completed the adjudication cycle and no more action will be taken.
* `F1` - Finalized/Payment - The claim/line has been paid.
* `F2` - Finalized/Denial - The claim/line has been denied.
* `F3` - Finalized/Revised - Adjudication information has been changed
* `F3F` - Finalized/Forwarded - The claim/encounter processing has been completed. Any applicable payment has been made and the claim/encounter has been forwarded to a subsequent entity as identified on the original claim or in this payer's records.
* `F3N` - Finalized/Not Forwarded - The claim/encounter processing has been completed. Any applicable payment has been made. The claim/encounter has NOT been forwarded to any subsequent entity identified on the original claim.
* `F4` - Finalized/Adjudication Complete - No payment forthcoming - The claim/encounter has been adjudicated and no further payment is forthcoming.
* `R0` - Requests for additional Information/General Requests - Requests that don't fall into other R - type categories.
* `R1` - Requests for additional Information/Entity Requests - Requests for information about specific entities (subscribers,patients,various providers).
* `R3` - Requests for additional Information/Claim/Line - Requests for information that could normally be submitted on a claim.
* `R4` - Requests for additional Information/Documentation - Requests for additional supporting documentation. Examples: certification,x - ray,notes.
* `R5` - Request for additional information/more specific detail - Additional information as a follow up to a previous request is needed. The original information was received but is inadequate. More specific/detailed information is requested.
* `R6` - Requests for additional information – Regulatory requirements
* `R7` - Requests for additional information – Confirm care is consistent with Health Plan policy coverage
* `R8` - Requests for additional information – Confirm care is consistent with health plan coverage exceptions
* `R9` - Requests for additional information – Determination of medical necessity
* `R10` - Requests for additional information – Support a filed grievance or appeal
* `R11` - Requests for additional information – Pre - payment review of claims
* `R12` - Requests for additional information – Clarification or justification of use for specified procedure code
* `R13` - Requests for additional information – Original documents submitted are not readable. Used only for subsequent request(s).
* `R14` - Requests for additional information – Original documents received are not what was requested. Used only for subsequent request(s).
* `R15` - Requests for additional information – Workers Compensation coverage determination.
* `R16` - Requests for additional information – Eligibility determination
* `R17` - Replacement of a Prior Request. Used to indicate that the current attachment request replaces a prior attachment request.
* `E0` - Response not possible - error on submitted request data
* `E1` - Response not possible - System Status
* `E2` - Information Holder is not responding; resubmit at a later time.
* `E3` - Correction required - relational fields in error.
* `E4` - Trading partner agreement specific requirement not met: Data correction required.
* `D0` - Data Search Unsuccessful - The payer is unable to return status on the requested claim(s) based on the submitted search criteria.
## ERA code lists
You may need to refer to the following code lists while evaluating the 835 ERA. Note that this page doesn't list all possible code lists, only those that are too long to properly represent within the API documentation.
### Claim Adjustment Group Code
This code is returned in the [`transactions.detailInfo.paymentInfo.claimAdjustments.claimAdjustmentGroupCode` property](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.claimAdjustments.claimAdjustmentGroupCode). It categorizes the adjustment reason codes returned in the `claimAdjustments` object.
* `CO` - Contractual Obligations | The payer uses this code when a joint payer/payee contractual agreement or a regulatory requirement resulted in an adjustment. An example of a contractual obligation might be a Participating Provider Agreement.
* `OA` - Other adjustments | The payer uses this code when the adjustment doesn't fall within the other categories.
* `PI` - Payor Initiated Reductions | The payer uses this code when, in their opinion, the adjustment is not the responsibility of the patient, but there is no supporting contract between the provider and the payer (i.e., medical review or professional review organization adjustments).
* `PR` - Patient Responsibility | The payer uses this code when the adjustment amount is the responsibility of the patient.
### Claim Adjustment Reason Code (CARC)
This code is returned in the following properties:
* [`transactions[].detailInfo[].paymentInfo[].claimAdjustments[].adjustmentReasonCode`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo\[].paymentInfo\[].claimAdjustments\[].adjustmentReasonCode1) (1-6)
* [`transactions[].detailInfo[].paymentInfo[].serviceLines[].serviceAdjustments[].adjustmentReasonCode`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo\[].paymentInfo\[].serviceLines\[].serviceAdjustments\[].adjustmentReasonCode1) (1-6)
CARCs identify the reason for an adjustment. Visit [Claim Adjustment Reason Codes](https://x12.org/codes/claim-adjustment-reason-codes) in the X12 documentation for a complete list.
### Claim Filing Indicator Code
This code is returned in the [`transactions.detailInfo.paymentInfo.claimPaymentInfo.claimFilingIndicatorCode` property](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.claimPaymentInfo.claimFilingIndicatorCode). It identifies the type of claim submitted.
* `12` - Preferred Provider Organization (PPO) | This code is also used for Blue Cross/Blue Shield participating provider arrangements.
* `13` - Point of Service (POS)
* `14` - Exclusive Provider Organization (EPO)
* `15` - Indemnity Insurance | This code is also used for Blue Cross/Blue Shield non-participating provider arrangements.
* `16` - Health Maintenance Organization (HMO) Medicare Risk
* `17` - Dental Maintenance Organization
* `AM` - Automobile Medical
* `CH` - Champus
* `DS` - Disability
* `HM` - Health Maintenance Organization
* `LM` - Liability Medical
* `MA` - Medicare Part A
* `MB` - Medicare Part B
* `MC` - Medicaid
* `OF` - Other Federal Program | This code is used for the Black Lung Program.
* `TV` - Title V
* `VA` - Veterans Affairs Plan
* `WC` - Workers' Compensation Health Claim
* `ZZ` - Mutually Defined
### Claim Status Code
This code is returned in the [`transactions.detailInfo.paymentInfo.claimPaymentInfo.claimStatusCode` property](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.claimPaymentInfo.claimStatusCode). It identifies the status of an entire claim as assigned by the payer, claim review organization, or repricing organization.
Codes `19`, `20`, and `21` indicate that the claim is a [crossover claim](/healthcare/receive-claim-responses#crossover-claims) that has been forwarded to an additional payer for processing. This practice is common in coordination of benefits (COB) scenarios. You may need to enroll the provider with the additional payer before they can process the claim.
* `1` - Processed as Primary | The payer uses this code when the claim was adjudicated by the current payer as primary regardless of whether any part of the claim was paid.
* `2` - Processed as Secondary | The payer uses this code when the claim was adjudicated by the current payer as secondary regardless of whether any part of the claim was paid.
* `3` - Processed as Tertiary | The payer uses this code when the claim was adjudicated by the current payer as tertiary (or subsequent) regardless of whether any part of the claim was paid.
* `4` - Denied | The payer uses this code when the Patient/Subscriber is not recognized, and the claim was not forwarded to another payer.
* `19` - Processed as Primary, Forwarded to Additional Payer(s)
* `20` - Processed as Secondary, Forwarded to Additional Payer(s)
* `21` - Processed as Tertiary, Forwarded to Additional Payer(s)
* `22` - Reversal of Previous Payment
* `23` - Not Our Claim, Forwarded to Additional Payer(s) | The payer sends this code when the patient/subscriber is not recognized or the claim was not adjudicated by the payer, but other payers are known and the claim has been forwarded to another payer.
* `25` - Predetermination Pricing Only - No Payment
### Credit or Debit Flag Code
This code is returned in the [`transactions.financialInformation.creditOrDebitFlagCode` property](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.financialInformation.creditOrDebitFlagCode). It indicates whether the payment is a credit or a debit.
* `C` - Credit | The payer uses this code to indicate a credit to the provider's account and a debit to the payer's account, initiated by the payer. In the case of an EFT, no additional action is required of the provider. The payer also uses this code when a check is issued for the payment.
* `D` - Debit | The payer uses this code to indicate a debit to the payer's account and a credit to the provider's account, initiated by the provider at the instruction of the payer.
### Payment Method Code
This code is returned in the [`transactions.financialInformation.paymentMethodCode` property](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.financialInformation.paymentMethodCode). It identifies the payment format. Note that the remaining properties in the `financialInformation` object contain additional requirements and information about the payment.
* `ACH` - Automated Clearing House (ACH) | The payer uses this code to move money electronically through the ACH, or to notify the provider that an ACH transfer was requested.
* `BOP` - Financial Institution Option | The payer uses this code to indicate that the third-party processor will choose the method of payment based upon endpoint requests or capabilities.
* `CHK` - Check | The payer uses this code to indicate that a check has been issued for payment.
* `FWT` - Federal Reserve Funds/Wire Transfer - Nonrepetitive | The payer uses this code to indicate that the funds were sent through the wire system.
* `NON` - Non-Payment Data | The payer uses this code when the `transactions.financialInformation.transactionHandlingCode` is `H`, indicating that this is information only and no dollars are to be moved.
### Provider Adjustment Reason Code
This code is returned in the [transactions\[\].providerAdjustments\[\].adjustments\[\].adjustmentReasonCode](https://www.stedi.com/docs/api-reference/healthcare/get-healthcare-reports-835#response.transactions.providerAdjustments\[].adjustments\[].adjustmentReasonCode) property.
This code identifies the reason for an adjustment made to the provider's account outside of the claim-level and service-line-level adjustments. The valid codes for X12 release 5010, which Stedi uses for ERAs, differ from the Provider Adjustment Reason Codes list on the X12 website. Use the following code list for ERAs you receive through Stedi.
* `50` - Late Charge | This is the Late Claim Filing Penalty or Medicare Late Cost Report Penalty
* `51` - Interest Penalty Charge | This is the interest assessment for late filing.
* `72` - Authorized Return | This is the provider refund adjustment. This adjustment acknowledges a refund received from a provider for previous overpayment. The payer should provide an identifying number in the `providerAdjustmentIdentifier` property. The adjustment amount is always a negative value.
* `90` - Early Payment Allowance
* `AH` - Origination Fee | This is the claim transmission fee. This is used for transmission fees that aren't specific to or dependent upon individual claims.
* `AM` - Applied to Borrower's Account | This identifies a loan repayment amount. This is capitation specific.
* `AP` - Acceleration of Benefits | This is the accelerated payment amount or withholding. A positive value for the adjustment represents a withholding. A negative value represents a payment.
* `B2` - Rebate | The provider has remitted an overpayment to the health plan in excess of the amount requested. The excess amount is being returned to the provider. The amount accepted by the health plan is reported using code `72` (Authorized Return) and is offset by the amount with code `WO` (Overpayment Recovery). This code reports the excess amount (represented as a negative adjustment amount) returned to the provider.
* `B3` - Recovery Allowance | This represents the check the payer received from the provider for overpayments from other payers. This is different from the provider refund adjustment represented by code `72` (Authorized Return). This adjustment should always be offset by another adjustment referring to the original refund request or reason.
* `BD` - Bad Debt Adjustment | This is the bad debt passthrough.
* `BN` - Bonus | This is capitation specific.
* `C5` - Temporary Allowance | This is the tentative adjustment.
* `CR` - Capitation Interest | This is capitation specific.
* `CS` - Adjustment
* `CT` - Capitation Payment | This is capitation specific.
* `CV` - Capital Passthru
* `CW` - Certified Registered Nurse Anesthetist Passthru
* `DM` - Direct Medical Education Passthru
* `E3` - Withholding
* `FB` - Forwarding Balance | This is the balance forward. A negative adjustment value represents a balance moving forward to a future ERA. A positive value represents a balance being applied from a previous ERA. The payer should provide a reference number for tracking purposes in the `providerAdjustmentIdentifier` property.
* `FC` - Fund Allocation | This is capitation specific.
* `GO` - Graduate Medical Education Passthru
* `HM` - Hemophilia Clotting Factor Supplement
* `IP` - Inceptive Premium Payment | This is capitation specific.
* `IR` - Internal Revenue Service Withholding
* `IS` - Interim Settlement | This is the interim rate lump sum adjustment.
* `J1` - Nonreimbursable | This offsets the claim or service level data that reflects what could be paid if not for demonstration program or other limitation that prevents issuance of payment.
* `L3` - Penalty | This is the capitation-related penalty. Withholding or release is identified by the sign of the adjustment amount.
* `L6` - Interest Owed | This is the interest paid on claims in this ERA.
* `LE` - Levy | IRS levy.
* `LS` - Lump Sum | This is the disproportionate share adjustment, indirect medical education passthrough, non-physician passthrough, passthrough lump sum adjustment, or other passthrough amount. The payer should identify the specific type of lump sum adjustment in the `providerAdjustmentIdentifier` property.
* `OA` - Organ Acquisition Passthru
* `OB` - Offset for Affiliated Providers | The payer should identify the affiliated providers in the `providerAdjustmentIdentifier` property.
* `PI` - Periodic Interim Payment | This is the periodic interim lump sum payments and reductions (PIP). The payments are made to a provider at the beginning of some period in advance of claims. These payments are advances on the expected claims for the period. The reductions are the recovery of actual claims payments during the period. For example, when a provider has a PIP payment, claims within this ERA covered by that payment are offset using this code to remove the claim payment from the current check. The sign of the adjustment amount determines whether this is a payment (negative) or reduction (positive). This payment and recoupment is effectively a loan to the provider and loan repayment.
* `PL` - Payment Final | This is the final settlement.
* `RA` - Retro-activity Adjustment | This is capitation specific.
* `RE` - Return on Equity
* `SL` - Student Loan Repayment
* `TL` - Third Party Liability | This is capitation specific.
* `WO` - Overpayment Recovery | This is the recovery of previous overpayment. The payer should provide an identifying number in the `providerAdjustmentIdentifier` property.
* `WU` - Unspecified Recovery | Medicare is currently using this code to represent penalty collections withheld for the IRS (an outside source).
### Remittance Advice Remark Code (RARC)
This code is returned in the following properties:
* [`transactions[].detailInfo[].paymentInfo[].inpatientAdjudication.claimPaymentRemarkCode`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo\[].paymentInfo\[].inpatientAdjudication.claimPaymentRemarkCode1) (1-6)
* [`transactions[].detailInfo[].paymentInfo[].outpatientAdjudication.claimPaymentRemarkCode`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo\[].paymentInfo\[].outpatientAdjudication.claimPaymentRemarkCode1) (1-6)
* [`transactions[].detailInfo[].paymentInfo[].serviceLines[].healthCareCheckRemarkCodes[].remarkCode`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo\[].paymentInfo\[].serviceLines\[].healthCareCheckRemarkCodes\[].remarkCode) - this property can either be a RARC or a National Council for Prescription Drug Programs Reject/Payment Code
RARCs provide additional explanation for an adjustment already described by a Claim Adjustment Reason Code (CARC) or convey information about remittance processing.
Visit [Remittance Advice Remark Codes](https://x12.org/codes/remittance-advice-remark-codes) in the X12 documentation for a complete list.
### Transaction Handling Code
This code is returned in the [`transactions.financialInformation.transactionHandlingCode` property](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.financialInformation.transactionHandlingCode). It indicates the actions taken by both the sender and the receiver.
* `C` - Payment Accompanies Remittance Advice | The payer uses this code to instruct the third-party processor to move funds and remittance details together through the banking system.
* `D` - Make Payment Only | The payer uses this code to instruct the third-party processor to move only funds through the banking system and to ignore any remittance information.
* `H` - Notification Only | The payer uses this code when the actual provider payment (listed in the `transactions.financialInformation.totalActualProviderPaymentAmount` property) is zero, and the transaction is not being used for Prenotification of Future Transfers. This indicates remittance information without any associated payment.
* `I` - Remittance Information Only | The payer uses this code to indicate to the payee that the remittance detail is moving separately from the payment.
* `P` - Prenotification of Future Transfers | This code is used only by the payer and the banking system to initially validate account numbers before beginning an EFT relationship.
* `U` - Split Payment and Remittance | The payer uses this code to instruct the third-party processor to split the payment and remittance details and send each on a separate path.
* `X` - Handling Party's Option to Split Payment and Remittance | The payer uses this code to instruct the third-party processor to move the payment and remittance detail, together or separately, based upon endpoint requests or capabilities.
# Sandbox accounts
Source: https://www.stedi.com/docs/healthcare/sandbox-account
***
title: Sandbox accounts
sidebarTitle: Sandbox accounts
------------------------------
A sandbox account is a test environment where you can explore integrating with the Stedi clearinghouse. It allows you to realistically simulate transactions without PHI/PII and evaluate Stedi's functionality without sending any data to payers.
You can [create a sandbox account](https://www.stedi.com/create-sandbox) in under five minutes for free without talking to our team or entering any payment information. When you're ready, [contact customer support](https://www.stedi.com/contact) to upgrade your account to a paid plan and start sending production data.
Mock transactions you send in the sandbox environment are free for testing
purposes and won’t incur any charges from Stedi.
## Send mock eligibility checks
You can submit mock real-time eligibility checks through the manual [eligibility check form](https://portal.stedi.com/app/healthcare/checks/create). You can choose from a variety of predefined requests for well-known payers, including:
* Aetna
* Cigna
* UnitedHealthcare
* National Centers for Medicare & Medicaid Services (CMS)
* Many more - Visit [Eligibility mock requests](/api-reference/healthcare/mock-requests-eligibility-checks) for a complete list
For each mock request, Stedi returns a realistic mock benefits response for that payer so you can get a sense for the kinds of data you'll receive in production. The benefits responses include examples of copays, deductibles, and other patient payment responsibilities, as well as active coverage.
You can also submit a mock [Medicare Beneficiary Identifier (MBI) lookup](/healthcare/mbi-lookup). MBI lookups allow you to use a patient's Social Security Number (SSN) to retrieve their MBI and complete benefits information from the Centers for Medicare and Medicaid Services (CMS).
### Test the Stedi Agent
The [Stedi Agent](/healthcare/eligibility-manager#stedi-agent) resolves recoverable eligibility check errors automatically with the same best practices our Support team uses for troubleshooting. You can run a specific mock eligibility check to evaluate the Stedi Agent:
1. Create a new eligibility check and select **Stedi Agent** as the payer. Keep all other properties set to their defaults.
2. Submit the check. It's designed to fail so you can watch the agent resolve issues in real time. Specifically, it returns `AAA` error `73` (Invalid/Missing Subscriber/Insured Name).
3. Click **Resolve with Stedi Agent**. The agent runs in **Debug view** to fix the error and eventually produce a successful mock eligibility response.
## Review eligibility check results
After you submit a mock eligibility check, you can review all of the request and response details in [Eligibility Manager](/healthcare/eligibility-manager). This includes:
* A list of historical eligibility checks that you can filter by status, payer ID, date, and error code.
* The raw API request and response.
* A user-friendly benefits view designed to help you quickly understand the patient's active coverage and payment responsibilities, such as co-pay and deductible amounts.
* Eligibility check **Debug** view, which allows you to to systematically troubleshoot failed checks until you receive a successful response from the payer.
## Explore the Stedi portal
The test environment allows you to get familiar with Stedi's UI tools and learn more about how you can use Stedi to automate claims and eligibility check workflows.
## Not supported
The following features aren't currently supported:
* [Raw X12 real-time eligibility checks](/api-reference/healthcare/post-healthcare-eligibility-raw-x12)
* [Batch eligibility checks](/healthcare/batch-refresh-eligibility-checks)
* [Transaction enrollment](/healthcare/transaction-enrollment)
* [Insurance discovery checks](/healthcare/insurance-discovery)
* [Coordination of benefits (COB) checks](/healthcare/coordination-of-benefits)
* Claims processing, including [837 claims submission](/healthcare/submit-professional-claims), [275 claim attachment](/healthcare/submit-claim-attachments), [277CA claim acknowledgments](/healthcare/receive-claim-responses#277ca-claim-acknowledgment), [835 ERAs](/healthcare/receive-claim-responses#835-electronic-remittance-advice-era), and [276/277 real-time claim status](/healthcare/check-claim-status)
* Custom mock data or payer selection
If you need to test these features, [contact us](https://www.stedi.com/contact) to request a free production trial. Most users are up and running in less than a day.
# Real-time eligibility checks
Source: https://www.stedi.com/docs/healthcare/send-eligibility-checks
***
title: Real-time eligibility checks
sidebarTitle: "Real-time eligibility checks"
--------------------------------------------
Real-time eligibility checks are ideal for in-person patient visits, telehealth appointments, and other scenarios where you need immediate information about a patient's coverage.
We recommend always starting with real-time checks when integrating with a new payer. This approach allows you to quickly test and refine your pipeline through fast feedback loops. Once you're comfortable with real-time checks, you may also want to start sending asynchronous batch checks to perform periodic refreshes for all or a subset of patients.
You can send real-time eligibility checks to payers manually through the Stedi portal or programmatically through the API. The synchronous response includes the patient's complete benefits information, such as coverage status, co-pays, and deductibles.
Eligibility checks verify coverage with a specific payer. If you don't know
the payer, you can perform an [insurance discovery
check](/healthcare/insurance-discovery) instead to find a patient's coverage
using their demographic data.
## Transaction enrollment
Some payers require [transaction enrollment](/healthcare/transaction-enrollment) before you can start sending them eligibility checks. The [Payer Network](https://www.stedi.com/healthcare/network) specifies which payers require enrollment.
## Testing
The best way to test real-time eligibility checks is through mock requests. When you submit specific mock requests, Stedi returns mock benefits data from the specified payer. You can submit mock requests through the:
* **JSON endpoint:** Visit [Eligibility mock requests](/api-reference/healthcare/mock-requests-eligibility-checks) for a complete list.
* **Stedi portal:** Visit [Test mode](/healthcare/test-mode) to learn how to enable **Test mode** in your account and manually submit mock requests.
### Don't send fake data
Some payers, particularly CMS (HETS), prohibit sending test eligibility checks for fake patients or providers to their production systems. Payers may block your access if you send these types of test transactions.
You can send as many [mock requests](/api-reference/healthcare/mock-requests-eligibility-checks) to Stedi as you need, but if you need to send test data to payers in production, you must contact [Stedi support](https://www.stedi.com/contact) to coordinate with the payer and obtain approval. For example, some payers require that you use specific test credentials.
## Manual submission
Manual eligibility checks can be useful for testing and for situations when you need to do a one-time eligibility check.
Go to the [Create manual eligibility check](https://portal.stedi.com/app/healthcare/checks/create) page in the Stedi portal to submit manual eligibility checks and review the full JSON response. You can also sort and filter a more user-friendly response organized by coverage type and level.
## API submission
Call one of the following endpoints to send real-time 270/271 eligibility checks to payers:
* [Eligibility Check](/api-reference/healthcare/post-healthcare-eligibility) to send requests in JSON
* [Eligibility Check Raw X12](/api-reference/healthcare/post-healthcare-eligibility-raw-x12) to send requests in X12 EDI
* [Eligibility Check SOAP](/api-reference/healthcare/post-healthcare-eligibility-soap) to send SOAP requests using the CAQH CORE vC2.2.0 XML Schema. The XML document contains an eligibility check in X12 EDI format.
Stedi automatically applies various repairs to help your requests meet X12 HIPAA specifications, resulting in fewer payer rejections.
### Headers
For the JSON and Raw X12 endpoints, you must include the following Stedi-specific headers in your API request:
* **`Authorization`:** [Generate an API key](/api-reference#authentication) to use for authentication.
* **`Content-Type`:** Set to `application/json`.
For the SOAP endpoint, you include authentication details in the XML document, so you only need the following header for requests:
* **`Content-Type`:** Set to `application/soap+xml`.
### Body - JSON
The information you provide to the payer in an eligibility check can vary, depending on the circumstances. We recommend starting with a basic eligibility request.
#### Basic eligibility request
Each eligibility check must include at least the following information in the request body:
| Information | Description |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tradingPartnerServiceId` | - This is the payer ID. Visit the [Payer Network](https://www.stedi.com/healthcare/network) for a complete list. You can send requests using the primary payer ID, the Stedi payer ID, or any alias listed in the payer record.
- If you don't know the payer, try submitting an [insurance discovery check](/healthcare/insurance-discovery) instead.
|
| `provider` object, name and identifier | - You must include the provider's name - either the `firstName` and `lastName` of a specific provider within a practice or the `organizationName`.
- You must include an identifier - this is typically the provider's [National Provider Identifier](https://www.stedi.com/docs/healthcare/national-provider-identifier) (`npi`). If the provider doesn't have an NPI, you can supply an alternative, such as their `taxId` or `ssn`.
|
| `subscriber` and/or `dependents` objects | - The `dependents` object is optional - refer to the scenarios when the [patient qualifies as a dependent](/healthcare/send-eligibility-checks#dependents).
- At a minimum, our API requires that you supply at least one of these fields in the request: `memberId`, `dateOfBirth`, or `lastName`. However, each payer has different requirements, so you should supply the fields necessary for each payer to identify the subscriber in their system.
- When all four of `memberId`, `dateOfBirth`, `firstName`, and `lastName` are provided, payers are required to return a response if the member is in their database. Some payers may be able to search with less information, but this varies by payer.
- We recommend always including the patient's member ID when possible. Learn more about [patient information](/healthcare/send-eligibility-checks#patient-information).
|
| `encounter` object, service dates | - You can specify either a single `dateOfService` or a `beginningDateOfService` and `endDateOfService`. The payer defaults to using the current date in their timezone if you don't include one.
- When checking eligibility for today, omit the `dateOfService` property to ensure consistent behavior across payers.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers such as the Centers for Medicare and Medicaid Services (CMS) do support requests for dates further in the future - especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `encounter` object, service or procedure codes | - Specify `serviceTypeCodes` and/or a `procedureCode` and `productOrServiceIDQualifier` to request specific types of benefits information.
- We recommend including no more than one service type code in each request.
- If you don't include any service type code or procedure code information, Stedi defaults to using `30` (Plan coverage and general benefits) as the only `serviceTypeCodes` value.
- Learn more about [STCs and procedure codes](/healthcare/eligibility-stc-procedure-codes).
|
The following example shows the bare minimum request body for an eligibility check. Because the `dateOfService` is not specified, the payer will use the current date in their timezone (default) to retrieve benefits information.
{/* schema:EligibilityCheckRequestContent */}
```json
{
"tradingPartnerServiceId": "AHS",
"encounter": {
"serviceTypeCodes": ["78"]
},
"provider": {
"organizationName": "ACME Health Services",
"npi": "1999999984"
},
"subscriber": {
"dateOfBirth": "19000101",
"firstName": "Jane",
"lastName": "Doe",
"memberId": "1234567890"
}
}
```
#### Conditional requirements
Note that objects marked as **required** are required for all requests, while others are conditionally required depending on the circumstances. When you include a conditionally required object, you must include all of its required properties.
For example, you must always include the `provider` object in your request, but you only need to include the `dependents` object when you need to request benefits information for a dependent on the subscriber's insurance plan.
### Body - X12 EDI
When sending real-time eligibility checks through the Raw X12 or SOAP endpoints, you must send the eligibility check [270 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-inquiry-x279a1/01GRYB6GTDJ4MEP5Z16CGMQWT6?__hstc=181257784.360aac417a3f93a63ca63bf29197fe1f.1727971380232.1752174670420.1752250096430.449&__hssc=181257784.244.1752250096430&__hsfp=1923652471). The information you send can vary, depending on the circumstances. We recommend starting with a basic eligibility request.
#### Basic eligibility request
Each eligibility check must also include at least the following information:
| Information | Description |
| ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BHT03` (Submitter Transaction Identifier) | - This identifier must be 1-50 characters long and different from the value you choose for `ST02`.
- We also strongly recommend using a unique value. [Learn more](/healthcare/send-eligibility-checks#submitter-transaction-identifier)
|
| `Loop 2100A` (Information Source) | - This loop contains the payer's information. Notably, you must include the payer's name (`NM103`) and identifier (`NM109`).
- The payer's identifier **must** be a payer ID or payer ID alias listed in the [Payer Network](https://www.stedi.com/healthcare/network?page=0). For example, you could use `60054`, `HPQRS`, `AETNA`, or any other listed payer ID alias for Aetna.
|
| `Loop 2000B` (Information Receiver) | - This loop contains information about the provider requesting the benefits information.
- You must include the provider's name (`NM103`) and an identifier (`NM109`). Most often this is the [National Provider Identifier (NPI)](/healthcare/national-provider-identifier).
|
| `Loop 2000C` (Subscriber) and `Loop 2000D` (Dependent) | - `Loop 2000D` is optional - refer to the scenarios when the [patient qualifies as a dependent](/healthcare/send-eligibility-checks#dependents).
- At a minimum, you must supply at least one of these fields in the appropriate loop to identify the patient: `NM109` (member ID), `DMG02` (birth date), or `NM103` (last name). However, each payer has different requirements, so you should supply the fields necessary for each payer to identify the patient in their system.
- When all four of member ID, first name, last name, and date of birth are provided, payers are required to return a response if the member is in their database. Some payers may be able to search with less information, but this varies by payer.
- We recommend always including the patient's member ID when possible. Learn more about [patient information](/healthcare/send-eligibility-checks#patient-information).
|
| `Loop 2110C` or `Loop 2100D DTP` (Eligibility/Benefit Date) | - You can specify either a single date of service or a range of service dates. The payer defaults to using the current date in their timezone if you don't include one.
- When checking eligibility for today, omit the service date from the request to ensure consistent behavior across payers.
- We recommend submitting dates up to 12 months in the past or up to the end of the current month. Payers aren't required to support dates outside these ranges. However, some payers such as the Centers for Medicare and Medicaid Services (CMS) do support requests for dates further in the future - especially the next calendar month. Check the payer's documentation to determine their specific behavior.
|
| `Loop 2110C` or `Loop 2100D EQ` (Eligibility or Benefit Inquiry) | - You must specify a service type code and/or a procedure code and qualifier to request specific types of benefits information.
- We recommend including no more than one service type code in each request. Learn more about [STCs and procedure codes](/healthcare/eligibility-stc-procedure-codes).
|
#### Envelope and header
Stedi generates its own `ISA` and `GS` headers and `IEA` and `GE` trailers before sending your eligibility check to the payer. You can submit your check to Stedi with any values in these segments, as long as they conform to the X12 EDI specification.
However, you must set `ST03` (Implementation Convention Reference) to `005010X279A1`.
#### Submitter Transaction Identifier
The `BHT03` (Submitter Transaction Identifier) element is **required** when submitting real-time eligibility checks in X12 EDI. The identifier you choose must be:
* An alphanumeric string from 1-50 characters long.
* Different from the value you choose for `ST02` (Transaction Set Control Number).
We also **strongly recommend** using a unique value. This approach makes it easier for Stedi to troubleshoot eligibility checks in your account.
The payer returns the identifier in the `BHT03` element of the 271 eligibility response, and Stedi returns it in the `meta.traceId` JSON property.
If you don't include `BHT03` in the request, Stedi returns a `200` with the `status` property set to `ERROR` and the `implementationTransactionSetSyntaxError` property set to `5`. The response also includes a negative [999 Implementation Acknowledgment](https://www.stedi.com/edi/x12/transaction-set/999) in the `x12` property.
{/* schema:EligibilityCheckResponseContent */}
```json
{
"controlNumber": "138549672",
"tradingPartnerServiceId": "STEDI",
"errors": [
{
"description": "The payer or clearinghouse rejected the request with validation errors. The original edi response is returned in the x12 field, please contact Stedi Support if you need further help."
}
],
"status": "ERROR",
"transactionSetAcknowledgement": "R",
"implementationTransactionSetSyntaxError": "5",
"x12": "ISA*00* *00* *ZZ*STEDI *01*117151744 *250523*1304*^*00501*000000000*0*P*:~GS*FA*STEDI*117151744*20250523*1304*000000000*X*005010X231A1~ST*999*0001*005010X231A1~AK1*HS*9872*005010X279A1~AK2*270*0001*005010X279A1~IK3*BHT*2**8~IK4*3*127*2~CTX*SITUATIONAL TRIGGER*BHT*2**3~IK5*R*5~AK9*R*1*1*0~SE*9*0001~GE*1*000000000~IEA*1*000000000~"
}
```
#### Trace Number
You may want to include a trace number in your request to help you track eligibility checks. Stedi always generates a trace number for internal tracking, and you can optionally supply your own trace number of up to 50 characters in a `TRN` segment.
You can send the trace number in **one** of the following locations (not both):
* If the subscriber is the patient, send it in `Loop 2000C TRN02` (Trace Number).
* If the dependent is the patient, send it in `Loop 2000D TRN02` (Dependent Trace Number).
Stedi returns both its internal trace number and your trace number (if provided) in the [`subscriberTraceNumbers` array](/api-reference/healthcare/post-healthcare-eligibility-raw-x12#response.subscriberTraceNumbers).
### Character restrictions
Only use the X12 Basic and Extended character sets in request data. Using characters outside these sets may cause validation and HTTP `400` errors.
The X12 Basic character set includes uppercase letters, digits, space, and some special characters. Lowercase letters and special language characters like `ñ` are not included.
The following special characters are included:

The Extended character set includes the characters listed in Basic, plus lowercase letters and additional special characters, such as `@`.
The following additional special characters are included:

In addition, the following characters are reserved for delimiters in the final X12 EDI transaction to the payer: `~`, `*`, `:`, and `^`. X12 doesn’t support using escape sequences to represent delimiters or special characters. Stedi returns a `400` error if you use these restricted characters improperly.
* **JSON endpoint:** Don’t include delimiter characters anywhere in your request data.
* **Raw X12 endpoint:** You can use these characters as delimiters, but not in the body of the request data.
#### Autocorrection for backticks
Stedi automatically replaces backticks (`` ` ``), also known as backquotes or grave accents, with an apostrophe (`'`) in `subscriber` and `dependents` first and last names. These corrections prevent errors when submitting your request. Stedi returns a message in the response's `warnings` array when it makes this replacement.
### Sample request and response
The following request and response examples show a basic eligibility check for a patient named Jane Doe. The request uses the `MH` service type code to check for mental health benefits.
The response contains the patient's benefits information. Visit [Determine patient benefits](/healthcare/eligibility-active-coverage-benefits) for detailed explanations of how to determine the patient's active coverage, financial responsibility, whether referrals and authorizations are required, and more.
#### JSON endpoint
{/* schema:EligibilityCheckRequestContent */}
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3 \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "ABDCE",
"encounter": {
"serviceTypeCodes": ["MH"]
},
"provider": {
"organizationName": "ACME Health Services",
"npi": "1999999984"
},
"subscriber": {
"dateOfBirth": "19000101",
"firstName": "Jane",
"lastName": "Doe",
"memberId": "1234567890"
}
}'
```
{/* schema:EligibilityCheckResponseContent */}
```json
{
"meta": {
"senderId": "030240928",
"submitterId": "117151744",
"applicationMode": "production",
"traceId": "01J2VZA127GH93JT74HJU",
"outboundTraceId": "01J2VZA127GH93JT74HJU"
},
"controlNumber": "214976898",
"reassociationKey": "123456789",
"tradingPartnerServiceId": "123456789",
"provider": {
"providerName": "ACME HEALTH SERVICES",
"entityIdentifier": "Provider",
"entityType": "Non-Person Entity",
"npi": "1999999984"
},
"subscriber": {
"memberId": "123456789",
"firstName": "JANE",
"lastName": "DOE",
"middleName": "A",
"gender": "F",
"entityIdentifier": "Insured or Subscriber",
"entityType": "Person",
"dateOfBirth": "19000101",
"groupNumber": "123456789",
"address": {
"address1": "1234 FIRST ST",
"city": "NEW YORK",
"state": "WV",
"postalCode": "123451111"
}
},
"payer": {
"entityIdentifier": "Payer",
"entityType": "Non-Person Entity",
"name": "ABCDE",
"federalTaxpayersIdNumber": "123412345",
"contactInformation": {
"contacts": [
{
"communicationMode": "Telephone",
"communicationNumber": "1234567890"
},
{
"communicationMode": "Uniform Resource Locator (URL)",
"communicationNumber": "website.company.com"
}
]
}
},
"planInformation": {
"groupNumber": "12341234",
"groupDescription": "ABCDE",
"priorIdNumber": "1234567890"
},
"planDateInformation": {
"planBegin": "20240101",
"planEnd": "20241231",
"eligibilityBegin": "20220102"
},
"planStatus": [
{
"statusCode": "1",
"status": "Active Coverage",
"planDetails": "Open Access Plus",
"serviceTypeCodes": ["30"]
},
{
"statusCode": "1",
"status": "Active Coverage",
"serviceTypeCodes": [
"A7",
"BC",
"A8",
"A4",
"A5",
"A6",
"7",
"4",
"BB",
"22"
]
},
{
"statusCode": "1",
"status": "Active Coverage",
"serviceTypeCodes": ["MH"]
}
],
"benefitsInformation": [
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"planCoverage": "Open Access Plus",
"additionalInformation": [
{
"description": "Complete Care Management"
}
]
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "6000",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Copay does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "500",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "3000",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
},
{
"description": "Copay does apply to member's out-of-pocket maximum"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "250",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "15000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "30000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"additionalInformation": [
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"benefitPercent": "0.1",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes"
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "7500",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "15000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"additionalInformation": [
{
"description": "Deductible does apply to member's out-of-pocket maximum"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"benefitPercent": "0.5",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"A7",
"BC",
"A8",
"A4",
"A5",
"A6",
"7",
"4",
"BB",
"22"
],
"serviceTypes": [
"Psychiatric - Inpatient",
"Day Care (Psychiatric)",
"Psychiatric - Outpatient",
"Psychiatric",
"Psychiatric - Room and Board",
"Psychotherapy",
"Anesthesia",
"Diagnostic X-Ray",
"Partial Hospitalization (Psychiatric)",
"Social Work"
],
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable"
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["BC", "A4", "A6", "4", "22"],
"serviceTypes": [
"Day Care (Psychiatric)",
"Psychiatric",
"Psychotherapy",
"Diagnostic X-Ray",
"Social Work"
],
"benefitAmount": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A8"],
"serviceTypes": ["Psychiatric - Outpatient"],
"benefitAmount": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "4", "22"],
"serviceTypes": [
"Psychiatric",
"Psychotherapy",
"Diagnostic X-Ray",
"Social Work"
],
"benefitAmount": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"benefitAmount": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "4", "22"],
"serviceTypes": [
"Psychiatric",
"Psychotherapy",
"Diagnostic X-Ray",
"Social Work"
],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Included For Specific Services"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Included For Specific Services"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "4", "22"],
"serviceTypes": [
"Psychiatric",
"Psychotherapy",
"Diagnostic X-Ray",
"Social Work"
],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["7"],
"serviceTypes": ["Anesthesia"],
"benefitPercent": "0",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "CB",
"name": "Coverage Basis",
"serviceTypeCodes": ["7", "BB"],
"serviceTypes": ["Anesthesia", "Partial Hospitalization (Psychiatric)"],
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes"
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["7"],
"serviceTypes": ["Anesthesia"],
"benefitAmount": "0",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["7"],
"serviceTypes": ["Anesthesia"],
"benefitPercent": "0",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["4"],
"serviceTypes": ["Diagnostic X-Ray"],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["4"],
"serviceTypes": ["Diagnostic X-Ray"],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["BB"],
"serviceTypes": ["Partial Hospitalization (Psychiatric)"],
"benefitAmount": "0",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["MH"],
"serviceTypes": ["Mental Health"],
"additionalInformation": [
{
"description": " Provider is out of network based on NPI ID provided in request."
}
]
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "5760",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Copay does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "500",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "2760",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
},
{
"description": "Copay does apply to member's out-of-pocket maximum"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "250",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "15000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "30000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"additionalInformation": [
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "7500",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "15000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"additionalInformation": [
{
"description": "Deductible does apply to member's out-of-pocket maximum"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
}
]
}
],
"errors": [],
"x12": "ISA*00* *00* *ZZ*STEDI *01*117151744 *111111*1234*^*00501*123456782*0*P*>~GS*HB*STEDI*117151744*20240326*111000*1*X*005010X279A1~ST*271*1001*005010X279A1~BHT*0022*11*01J2VZA127GH93JT74HJU*20240326*1514~HL*1**20*1~NM1*PR*2*ABCDE*****FI*111000123~PER*IC**TE*123456789*UR*website.company.com~HL*2*1*21*1~NM1*1P*2*ACME HEALTH SERVICES*****XX*1999999984~HL*3*2*22*0~NM1*IL*1*DOE*JANE*A***MI*123456789~REF*6P*123456789*ABCDE~REF*Q4*123456789~N3*1234 FIRST ST~N4*NEW YORK*WV*123451111~DMG*D8*19000101*F~INS*Y*18*001*25~DTP*356*D8*20220102~DTP*346*D8*20240101~DTP*347*D8*20241231~EB*1**30**Open Access Plus~MSG*Complete Care Management~EB*G*FAM*30***23*6000.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*FAM*30***23*500.00*****Y~MSG*Includes services provided by Client Specific Network~EB*G*IND*30***23*3000.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***23*250.00*****Y~MSG*Includes services provided by Client Specific Network~EB*C*FAM*30***23*15000.00*****N~EB*G*FAM*30***23*30000.00*****N~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*A*IND*30*****.10****Y~EB*C*IND*30***23*7500.00*****N~EB*G*IND*30***23*15000.00*****N~MSG*Deductible does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~EB*A*IND*30*****.50****N~EB*1**A7^BC^A8^A4^A5^A6^7^4^BB^22*********W~EB*C*IND*BC^A4^A6^4^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*22~EB*C*IND*A8****0.00****N*Y~MSG*Includes services provided by Client Specific Network~EB*C*IND*A4^A6^4^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*11~EB*C*IND*A4^A6^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*02~EB*B*IND*A4^A6^22***27*20.00****N*Y~III*ZZ*11~EB*A*IND*A4^A6^4^22*****.00***N*Y~III*ZZ*11~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Included For Specific Services~III*ZZ*02~EB*A*IND*A4^A6^22*****.00***N*Y~MSG*Included For Specific Services~III*ZZ*02~EB*A*IND*A4^A6^22*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*02~EB*A*IND*A4^A6^4^22*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*02~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*A*IND*7*****.00***Y*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*CB**7^BB********Y*Y~EB*C*IND*7****0.00****Y*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*11~EB*A*IND*7*****.00***Y*Y~III*ZZ*11~EB*A*IND*4*****.00***N*Y~III*ZZ*22~EB*A*IND*4*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*22~EB*C*IND*BB****0.00****Y*Y~MSG*Includes services provided by Client Specific Network~EB*1**MH~MSG* Provider is out of network based on NPI ID provided in request.~EB*G*FAM*30***29*5760.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*FAM*30***29*500.00*****Y~MSG*Includes services provided by Client Specific Network~EB*G*IND*30***29*2760.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***29*250.00*****Y~MSG*Includes services provided by Client Specific Network~EB*C*FAM*30***29*15000.00*****N~EB*G*FAM*30***29*30000.00*****N~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***29*7500.00*****N~EB*G*IND*30***29*15000.00*****N~MSG*Deductible does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~SE*119*1001~GE*1*1~IEA*1*123456782~"
}
```
#### Raw X12 endpoint
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3/raw-x12 \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"x12": "ISA*00* *00* *ZZ*SENDER *ZZ*RECEIVER *231106*1406*^*00501*000000001*0*T*>~GS*HS*SENDERGS*RECEIVERGS*20231106*140631*000000001*X*005010X279A1~ST*270*123456789*005010X279A1~BHT*0022*13*10001234*20240321*1319~HL*1**20*1~NM1*PR*2*ABCDE*****PI*11122~HL*2*1*21*1~NM1*1P*2*ACME HEALTH SERVICES*****SV*1999999984~HL*3*2*22*0~TRN*1*11122-12345*1234567890~NM1*IL*1*JANE*DOE****MI*1234567890~DMG*D8*19000101~DTP*291*D8*20240108~EQ*MH~SE*13*123456789~GE*1*000000001~IEA*1*000000001~"
}'
```
{/* schema:EligibilityCheckResponseContent */}
```json
{
"meta": {
"senderId": "030240928",
"submitterId": "117151744",
"applicationMode": "production",
"traceId": "01J2VZA127GH93JT74HJU",
"outboundTraceId": "01J2VZA127GH93JT74HJU"
},
"controlNumber": "214976898",
"reassociationKey": "123456789",
"tradingPartnerServiceId": "123456789",
"provider": {
"providerName": "ACME HEALTH SERVICES",
"entityIdentifier": "Provider",
"entityType": "Non-Person Entity",
"npi": "1999999984"
},
"subscriber": {
"memberId": "123456789",
"firstName": "JANE",
"lastName": "DOE",
"middleName": "A",
"gender": "F",
"entityIdentifier": "Insured or Subscriber",
"entityType": "Person",
"dateOfBirth": "19000101",
"groupNumber": "123456789",
"address": {
"address1": "1234 FIRST ST",
"city": "NEW YORK",
"state": "WV",
"postalCode": "123451111"
}
},
"payer": {
"entityIdentifier": "Payer",
"entityType": "Non-Person Entity",
"name": "ABCDE",
"federalTaxpayersIdNumber": "123412345",
"contactInformation": {
"contacts": [
{
"communicationMode": "Telephone",
"communicationNumber": "1234567890"
},
{
"communicationMode": "Uniform Resource Locator (URL)",
"communicationNumber": "website.company.com"
}
]
}
},
"planInformation": {
"groupNumber": "12341234",
"groupDescription": "ABCDE",
"priorIdNumber": "1234567890"
},
"planDateInformation": {
"planBegin": "20240101",
"planEnd": "20241231",
"eligibilityBegin": "20220102"
},
"planStatus": [
{
"statusCode": "1",
"status": "Active Coverage",
"planDetails": "Open Access Plus",
"serviceTypeCodes": ["30"]
},
{
"statusCode": "1",
"status": "Active Coverage",
"serviceTypeCodes": [
"A7",
"BC",
"A8",
"A4",
"A5",
"A6",
"7",
"4",
"BB",
"22"
]
},
{
"statusCode": "1",
"status": "Active Coverage",
"serviceTypeCodes": ["MH"]
}
],
"benefitsInformation": [
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"planCoverage": "Open Access Plus",
"additionalInformation": [
{
"description": "Complete Care Management"
}
]
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "6000",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Copay does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "500",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "3000",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
},
{
"description": "Copay does apply to member's out-of-pocket maximum"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "250",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "15000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "30000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"additionalInformation": [
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"benefitPercent": "0.1",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes"
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "7500",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "23",
"timeQualifier": "Calendar Year",
"benefitAmount": "15000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"additionalInformation": [
{
"description": "Deductible does apply to member's out-of-pocket maximum"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"benefitPercent": "0.5",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": [
"A7",
"BC",
"A8",
"A4",
"A5",
"A6",
"7",
"4",
"BB",
"22"
],
"serviceTypes": [
"Psychiatric - Inpatient",
"Day Care (Psychiatric)",
"Psychiatric - Outpatient",
"Psychiatric",
"Psychiatric - Room and Board",
"Psychotherapy",
"Anesthesia",
"Diagnostic X-Ray",
"Partial Hospitalization (Psychiatric)",
"Social Work"
],
"inPlanNetworkIndicatorCode": "W",
"inPlanNetworkIndicator": "Not Applicable"
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["BC", "A4", "A6", "4", "22"],
"serviceTypes": [
"Day Care (Psychiatric)",
"Psychiatric",
"Psychotherapy",
"Diagnostic X-Ray",
"Social Work"
],
"benefitAmount": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A8"],
"serviceTypes": ["Psychiatric - Outpatient"],
"benefitAmount": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "4", "22"],
"serviceTypes": [
"Psychiatric",
"Psychotherapy",
"Diagnostic X-Ray",
"Social Work"
],
"benefitAmount": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"benefitAmount": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "4", "22"],
"serviceTypes": [
"Psychiatric",
"Psychotherapy",
"Diagnostic X-Ray",
"Social Work"
],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Included For Specific Services"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Included For Specific Services"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "4", "22"],
"serviceTypes": [
"Psychiatric",
"Psychotherapy",
"Diagnostic X-Ray",
"Social Work"
],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "02",
"industry": "Telehealth Provided Other than in Patient’s Home"
}
]
},
{
"code": "B",
"name": "Co-Payment",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["A4", "A6", "22"],
"serviceTypes": ["Psychiatric", "Psychotherapy", "Social Work"],
"timeQualifierCode": "27",
"timeQualifier": "Visit",
"benefitAmount": "20",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["7"],
"serviceTypes": ["Anesthesia"],
"benefitPercent": "0",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "CB",
"name": "Coverage Basis",
"serviceTypeCodes": ["7", "BB"],
"serviceTypes": ["Anesthesia", "Partial Hospitalization (Psychiatric)"],
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes"
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["7"],
"serviceTypes": ["Anesthesia"],
"benefitAmount": "0",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["7"],
"serviceTypes": ["Anesthesia"],
"benefitPercent": "0",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "11",
"industry": "Office"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["4"],
"serviceTypes": ["Diagnostic X-Ray"],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
}
]
},
{
"code": "A",
"name": "Co-Insurance",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["4"],
"serviceTypes": ["Diagnostic X-Ray"],
"benefitPercent": "0",
"authOrCertIndicator": "N",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Services rendered thru Client Specific Network"
}
],
"eligibilityAdditionalInformation": {
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
},
"eligibilityAdditionalInformationList": [
{
"codeListQualifierCode": "ZZ",
"codeListQualifier": "Mutually Defined",
"industryCode": "22",
"industry": "Outpatient Hospital"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["BB"],
"serviceTypes": ["Partial Hospitalization (Psychiatric)"],
"benefitAmount": "0",
"authOrCertIndicator": "Y",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "1",
"name": "Active Coverage",
"serviceTypeCodes": ["MH"],
"serviceTypes": ["Mental Health"],
"additionalInformation": [
{
"description": " Provider is out of network based on NPI ID provided in request."
}
]
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "5760",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Copay does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "500",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "2760",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
},
{
"description": "Copay does apply to member's out-of-pocket maximum"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "250",
"inPlanNetworkIndicatorCode": "Y",
"inPlanNetworkIndicator": "Yes",
"additionalInformation": [
{
"description": "Includes services provided by Client Specific Network"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "15000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "FAM",
"coverageLevel": "Family",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "30000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"additionalInformation": [
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
},
{
"description": "Deductible does apply to member's out-of-pocket maximum"
}
]
},
{
"code": "C",
"name": "Deductible",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "7500",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No"
},
{
"code": "G",
"name": "Out of Pocket (Stop Loss)",
"coverageLevelCode": "IND",
"coverageLevel": "Individual",
"serviceTypeCodes": ["30"],
"serviceTypes": ["Health Benefit Plan Coverage"],
"timeQualifierCode": "29",
"timeQualifier": "Remaining",
"benefitAmount": "15000",
"inPlanNetworkIndicatorCode": "N",
"inPlanNetworkIndicator": "No",
"additionalInformation": [
{
"description": "Deductible does apply to member's out-of-pocket maximum"
},
{
"description": "Coinsurance does apply to member's out-of-pocket maximum"
}
]
}
],
"errors": [],
"x12": "ISA*00* *00* *ZZ*STEDI *01*117151744 *111111*1234*^*00501*123456782*0*P*>~GS*HB*STEDI*117151744*20240326*111000*1*X*005010X279A1~ST*271*1001*005010X279A1~BHT*0022*11*01J2VZA127GH93JT74HJU*20240326*1514~HL*1**20*1~NM1*PR*2*ABCDE*****FI*111000123~PER*IC**TE*123456789*UR*website.company.com~HL*2*1*21*1~NM1*1P*2*ACME HEALTH SERVICES*****XX*1999999984~HL*3*2*22*0~NM1*IL*1*DOE*JANE*A***MI*123456789~REF*6P*123456789*ABCDE~REF*Q4*123456789~N3*1234 FIRST ST~N4*NEW YORK*WV*123451111~DMG*D8*19000101*F~INS*Y*18*001*25~DTP*356*D8*20220102~DTP*346*D8*20240101~DTP*347*D8*20241231~EB*1**30**Open Access Plus~MSG*Complete Care Management~EB*G*FAM*30***23*6000.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*FAM*30***23*500.00*****Y~MSG*Includes services provided by Client Specific Network~EB*G*IND*30***23*3000.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***23*250.00*****Y~MSG*Includes services provided by Client Specific Network~EB*C*FAM*30***23*15000.00*****N~EB*G*FAM*30***23*30000.00*****N~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*A*IND*30*****.10****Y~EB*C*IND*30***23*7500.00*****N~EB*G*IND*30***23*15000.00*****N~MSG*Deductible does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~EB*A*IND*30*****.50****N~EB*1**A7^BC^A8^A4^A5^A6^7^4^BB^22*********W~EB*C*IND*BC^A4^A6^4^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*22~EB*C*IND*A8****0.00****N*Y~MSG*Includes services provided by Client Specific Network~EB*C*IND*A4^A6^4^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*11~EB*C*IND*A4^A6^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*02~EB*B*IND*A4^A6^22***27*20.00****N*Y~III*ZZ*11~EB*A*IND*A4^A6^4^22*****.00***N*Y~III*ZZ*11~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Included For Specific Services~III*ZZ*02~EB*A*IND*A4^A6^22*****.00***N*Y~MSG*Included For Specific Services~III*ZZ*02~EB*A*IND*A4^A6^22*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*02~EB*A*IND*A4^A6^4^22*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*02~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*A*IND*7*****.00***Y*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*CB**7^BB********Y*Y~EB*C*IND*7****0.00****Y*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*11~EB*A*IND*7*****.00***Y*Y~III*ZZ*11~EB*A*IND*4*****.00***N*Y~III*ZZ*22~EB*A*IND*4*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*22~EB*C*IND*BB****0.00****Y*Y~MSG*Includes services provided by Client Specific Network~EB*1**MH~MSG* Provider is out of network based on NPI ID provided in request.~EB*G*FAM*30***29*5760.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*FAM*30***29*500.00*****Y~MSG*Includes services provided by Client Specific Network~EB*G*IND*30***29*2760.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***29*250.00*****Y~MSG*Includes services provided by Client Specific Network~EB*C*FAM*30***29*15000.00*****N~EB*G*FAM*30***29*30000.00*****N~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***29*7500.00*****N~EB*G*IND*30***29*15000.00*****N~MSG*Deductible does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~SE*119*1001~GE*1*1~IEA*1*123456782~"
}
```
#### SOAP endpoint
```bash
curl --request POST \
--url "https://healthcare.us.stedi.com/2025-06-01/protocols/caqh-core" \
--header "Content-Type: application/soap+xml" \
--data '
STEDI-ACCOUNT-ID
STEDI-API-KEY
X12_270_Request_005010X279A1
RealTime
YOUR-PAYLOAD-ID
2024-07-29T12:00:00Z
SENDER-ID
RECEIVER-ID
2.2.0
~GS*HS*SENDERGS*RECEIVERGS*20231106*140631*000000001*X*005010X279A1~ST*270*1234*005010X279A1~BHT*0022*13*10001234*20240321*1319~HL*1**20*1~NM1*PR*2*ABCDE*****PI*11122~HL*2*1*21*1~NM1*1P*2*ACME HEALTH SERVICES*****SV*1999999984~HL*3*2*22*0~TRN*1*11122-12345*1234567890~NM1*IL*1*JANE*DOE****MI*123456789~DMG*D8*19000101~DTP*291*D8*20240108~EQ*MH~SE*13*1234~GE*1*000000001~IEA*1*000000001~]]>
'
```
```xml
X12_271_Response_005010X279A1
RealTime
f81d4fae-7dec-11d0-a765-00a0c91e6b12
2024-07-28T12:01:22.000Z
RECEIVER_ID
STEDI
2.2.0
~GS*HB*STEDI*117151744*20240326*111000*1*X*005010X279A1~ST*271*1001*005010X279A1~BHT*0022*11*01J2VZA127GH93JT74HJU*20240326*1514~HL*1**20*1~NM1*PR*2*ABCDE*****FI*111000123~PER*IC**TE*123456789*UR*website.company.com~HL*2*1*21*1~NM1*1P*2*ACME HEALTH SERVICES*****XX*1999999984~HL*3*2*22*0~NM1*IL*1*DOE*JANE*A***MI*123456789~REF*6P*123456789*ABCDE~REF*Q4*123456789~N3*1234 FIRST ST~N4*NEW YORK*WV*123451111~DMG*D8*19000101*F~INS*Y*18*001*25~DTP*356*D8*20220102~DTP*346*D8*20240101~DTP*347*D8*20241231~EB*1**30**Open Access Plus~MSG*Complete Care Management~EB*G*FAM*30***23*6000.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*FAM*30***23*500.00*****Y~MSG*Includes services provided by Client Specific Network~EB*G*IND*30***23*3000.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***23*250.00*****Y~MSG*Includes services provided by Client Specific Network~EB*C*FAM*30***23*15000.00*****N~EB*G*FAM*30***23*30000.00*****N~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*A*IND*30*****.10****Y~EB*C*IND*30***23*7500.00*****N~EB*G*IND*30***23*15000.00*****N~MSG*Deductible does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~EB*A*IND*30*****.50****N~EB*1**A7^BC^A8^A4^A5^A6^7^4^BB^22*********W~EB*C*IND*BC^A4^A6^4^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*22~EB*C*IND*A8****0.00****N*Y~MSG*Includes services provided by Client Specific Network~EB*C*IND*A4^A6^4^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*11~EB*C*IND*A4^A6^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*02~EB*B*IND*A4^A6^22***27*20.00****N*Y~III*ZZ*11~EB*A*IND*A4^A6^4^22*****.00***N*Y~III*ZZ*11~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Included For Specific Services~III*ZZ*02~EB*A*IND*A4^A6^22*****.00***N*Y~MSG*Included For Specific Services~III*ZZ*02~EB*A*IND*A4^A6^22*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*02~EB*A*IND*A4^A6^4^22*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*02~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*A*IND*7*****.00***Y*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*CB**7^BB********Y*Y~EB*C*IND*7****0.00****Y*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*11~EB*A*IND*7*****.00***Y*Y~III*ZZ*11~EB*A*IND*4*****.00***N*Y~III*ZZ*22~EB*A*IND*4*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*22~EB*C*IND*BB****0.00****Y*Y~MSG*Includes services provided by Client Specific Network~EB*1**MH~MSG* Provider is out of network based on NPI ID provided in request.~EB*G*FAM*30***29*5760.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*FAM*30***29*500.00*****Y~MSG*Includes services provided by Client Specific Network~EB*G*IND*30***29*2760.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***29*250.00*****Y~MSG*Includes services provided by Client Specific Network~EB*C*FAM*30***29*15000.00*****N~EB*G*FAM*30***29*30000.00*****N~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***29*7500.00*****N~EB*G*IND*30***29*15000.00*****N~MSG*Deductible does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~SE*119*1001~GE*1*1~IEA*1*123456782~]]>
Success
```
### Retries
Implementing the right retry strategy for eligibility check failures saves a lot of time and money.
At a minimum, we **strongly recommend** automatically retrying every request that fails due to payer connectivity issues. Automatic retries resolve a significant portion of these types of failures without manual intervention. Visit [Retry strategy](/healthcare/eligibility-troubleshooting#retry-strategy) for details.
### Timeout
Insurance payers may take up to 60 seconds to respond to a request, but Stedi holds real-time eligibility check requests open for up to 120 seconds before timing out. During this period, Stedi attempts multiple retries to payers in an effort to complete your request.
Canceling and retrying requests before Stedi's automatic retry period ends may create multiple ongoing requests to payers and increase your concurrency usage.
#### Request hedging
When eligibility responses are taking too long, you can use request hedging to try to get results faster. To implement request hedging, send a second request at some internal duration cutoff (for example, 30 seconds) without cancelling the first request. Then, you can use whichever result comes back first. If one of the requests fails, you can wait for the second request to see if it's successful.
### Concurrency limit
Our real-time eligibility check endpoints share a concurrency pool with other real-time healthcare APIs. For more information, visit [Concurrency Limits](/api-reference#concurrency-limits).
### Recommended API clients
You may want to use an API client to make testing and debugging easier.
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.
Visit [API clients](/api-reference#api-clients) for a list of recommended clients you can use instead.
## Patient information
All payers are required to be able to search for patients using the following "bare minimum" subsets of information. They will return benefits information as long as they can find a unique match for the patient within their system.
For a subscriber:
* Member ID, first name, last name, date of birth
* Member ID, last name, date of birth
* Member ID, first name, last name
For a dependent:
* Subscriber member ID (in the `subscriber` object), first name, last name, date of birth
* Subscriber member ID, last name, date of birth
* Subscriber member ID, first name, last name
Of course, not all of this patient information is always available. For example, a patient may forget their ID card. In these instances, some payers may still be able to search with even less information, such as the patient's first name, last name, and date of birth. Contact us if you have questions about alternative search options for a particular payer.
### Dependents
The patient qualifies as a dependent for eligibility checks when:
1. The patient is listed as a dependent on the subscriber's insurance plan.
2. The payer cannot uniquely identify the patient through information outside the subscriber's policy.
When the patient meets these criteria, you should submit their information in the `dependents` array (JSON) or `Loop 2000D` (X12 EDI). Otherwise, you must submit their information in the `subscriber` object (JSON) or `Loop 2000C` (X12 EDI) instead.
For example, if the dependent has their own member ID number in the payer's database, you must identify them as a subscriber. This includes member IDs that differ only by a suffix, such as `01`, because the patient can still be uniquely identified.
#### Medicaid dependents
Most Medicaid plans don't support dependents. However, some state Medicaid plans support eligibility inquiries for newborn children under 12 months old.
Children typically must be enrolled in Medicaid as a separate subscriber with their own unique member ID, even if they are legally the dependent of a parent who is a Medicaid plan member. Therefore, you'll almost always need to submit the child as a subscriber in the `subscriber` object (JSON) or `Loop 2000C` (X12 EDI).
Sending the `dependents` array (JSON) or `Loop 2000D` (X12 EDI) to payers that don't support dependents will either cause an error, or the payer may ignore the information and return results for the subscriber instead.
### Patient names
Note the following information and best practices when entering patient names:
* Enter the name exactly as written on the patient's insurance ID card (if available), including any special or punctuation characters such as apostrophes, hyphens (dashes), or spaces. If the patient's insurance ID card isn't available, enter the name exactly as written on a government-issued ID card. If a government ID card isn't available, enter the name exactly as given by the patient.
* Don't include a name prefix, title, rank, honorific, or academic degree in any property. These include Mrs., Dr., Hon., and PhD.
* Don't include a suffix or generation such as Jr. or III in the `firstName` or `lastName` property. Put it in the separate `suffix` property instead. Payers are supposed to automatically parse suffixes out of the last name, but Stedi can't guarantee that all payers will do this correctly.
* You can populate a middle name (or names) or initial in the `middleName` property, but most payers ignore it when searching for the patient.
* Case doesn't matter. For example, JANE is equivalent to Jane.
The following are supported for patient names:
* Compound last and first names separated by spaces or hyphens such as Jean‐Claude or Smith Jones
* Apostrophized or elided names such as O’Connor or D’Amore
* Numbers like 3, however this typically indicates a data entry error
Some payers may have more specific requirements or restrictions that we don't cover in our docs. If you're receiving errors for a specific payer, we recommend consulting that payer's documentation for eligibility checks for additional guidance.
### MBI for CMS checks
A Medicare Beneficiary Identifier (MBI) is a unique, randomly-generated identifier assigned to individuals enrolled in Medicare. You must include the patient's MBI in every eligibility check to the Centers for Medicare and Medicaid Services (payer ID: CMS).
Some payers return the patient's MBI in one of the following properties of the standard eligibility response:
* [`benefitsInformation.benefitsAdditionalInformation.hicNumber`](/api-reference/healthcare/post-healthcare-eligibility#response.benefitsInformation.benefitsAdditionalInformation.hicNumber)
* [`planInformation.hicNumber`](/api-reference/healthcare/post-healthcare-eligibility#response.planInformation.hicNumber)
If the value in either of these properties matches the format specified in the [Medicare Beneficiary Identifier documentation](https://www.cms.gov/training-education/partner-outreach-resources/new-medicare-card/medical-beneficiary-identifiers-mbis), the number is likely an MBI, and we recommend sending a follow-up eligibility check to CMS for additional benefits data. You're most likely to receive an MBI in eligibility check responses from commercial Medicare Advantage plans, but they can also be present in responses from Medicaid plans for dual-eligible patients.
When you don't know a patient's MBI, you can use Stedi's eligibility check APIs to perform an MBI lookup using their Social Security Number instead. Stedi returns a complete benefits response from CMS with the patient's MBI in the `subscriber` object for future reference. Visit [Medicare Beneficiary Identifier (MBI) lookup
](/healthcare/mbi-lookup) for complete details.
**Don't** submit eligibility checks for Medicare Advantage plans to CMS (HETS) - you should submit them to the actual Medicare Advantage plan payer instead.
# Claim attachments
Source: https://www.stedi.com/docs/healthcare/submit-claim-attachments
***
title: "Claim attachments"
sidebarTitle: "Attachments"
---------------------------
Claim attachments are additional documents that help justify or validate a claim. They're typically required when the claim alone doesn't provide enough information for the payer to make a decision, such as when a procedure is unusual, high-cost, or uses an unlisted code.
Attachments can include medical records, treatment plans, radiographs, photographs, itemized bills, and letters from providers - the type required for each claim depends on the services listed and the payer's rules. For example, a claim for a dental crown may require X-rays, while a claim for a surgery may require an operative report.
You can submit unsolicited 275 claim attachments for professional and dental claims in either JSON or X12 EDI format. Attachments for institutional claims aren't supported.
## Transaction enrollment
Some payers require enrollment before allowing providers to submit 275 claim attachments. This enrollment process is separate from the transaction enrollment process for 837 claims.
The [Payer Network](https://www.stedi.com/healthcare/network?query=eyIyNzAiOnt9LCIyNzYiOnt9LCI4MzUiOnt9LCI4MzdQIjp7fSwiODM3SSI6e30sIjgzN0QiOnt9LCJDT0IiOnt9LCIyNzVTIjp7ImlzU3VwcG9ydGVkIjp0cnVlfSwiMjc1VSI6eyJpc1N1cHBvcnRlZCI6dHJ1ZX19\&page=0) lists which payers require transaction enrollment for 275 claim attachments. Visit [transaction enrollment](/healthcare/transaction-enrollment) for details about the transaction enrollment process.
## JSON submission
You can submit [unsolicited claim attachments](#solicited-vs-unsolicited-attachments) through Stedi JSON APIs. Submitting claim attachments in JSON requires three steps:
Call the [Create Claim Attachment (275) JSON](/api-reference/healthcare/post-healthcare-create-claim-attachment) endpoint to receive a pre-signed URL that you can use to upload the attachment file to Stedi.
The response also contains an `attachmentId` that you'll include in the claim submission.
Use a `PUT` request to upload the attachment file to the pre-signed URL (`uploadUrl`) in the response. The request must include a `Content-Type` header that matches the MIME type you specified for the attachment file.
The following example shows how to upload a JPEG attachment:
```bash
curl --request PUT \
--url "" \
--header "Content-Type: image/jpeg" \
--upload-file /path/to/file.jpeg
```
We recommend limiting attachments to 64MB each, but some payers may have different size requirements. When in doubt, check the payer's documentation to determine their specific limits. Stedi stores uploaded files for 45 days. After that, you must reupload the attachment file before you can submit it to the payer.
Call one of the following claim submission endpoints:
* [Professional Claims JSON](/api-reference/healthcare/post-healthcare-claims)
* [Dental Claims JSON](/api-reference/healthcare/post-healthcare-dental-claims)
You must include [specific properties](#reference-attachments-in-a-claim) in your request to identify the attachment and tell Stedi which attachment file to use. These properties are `attachmentReportTypeCode`, `attachmentTransmissionCode`, and `attachmentId`.
Stedi sends the claim and the claim attachment to the payer and then returns summary information about the claim submission.
The payer processes the claim and attachment together, and sends back [277CA and 835 ERA responses](/healthcare/submit-claim-attachments#payer-responses).
## X12 EDI submission
You can submit [unsolicited claim attachments](#solicited-vs-unsolicited-attachments) in X12 EDI format through the API or SFTP. We recommend this approach when you have an existing system that generates X12 EDI files and you want to send them through Stedi.
With X12 EDI submissions, you don't need to upload the attachment file to Stedi first - you can send the entire 275 transaction directly to the payer.
#### API
Call one of the following endpoints:
* [Professional Claims Raw X12](/api-reference/healthcare/post-healthcare-claims-raw-x12)
* [Dental Claims Raw X12](/api-reference/healthcare/post-healthcare-dental-claims-raw-x12)
In addition to the claim information, you must include [specific elements](#reference-attachments-in-a-claim) in either `Loop 2300` or `Loop 2400` (professional claims only) to identify the attachment. These elements are `PWK01`, `PWK02`, and `PWK06`.
Call the [Submit Claim Attachment (275) X12 EDI](/api-reference/healthcare/post-healthcare-submit-claim-attachment-raw-x12) endpoint. Stedi sends the 275 transaction to the payer and returns summary information about the submission.
* **Payer ID:** You must submit a payer identifier in `Loop 1000A NM109` so Stedi can route the attachment to the correct payer. This identifier **must** be a payer ID or payer ID alias listed in the [Payer Network](https://www.stedi.com/healthcare/network). For example, you could use `60054`, `HPQRS`, `AETNA`, or any other listed payer ID alias for Aetna.
* The size limit for attachments submitted in a single API request is 6MB. If you need to submit larger attachment files, you must submit them through Stedi SFTP or the JSON endpoints.
Once received, the payer processes the claim and attachment together, and sends back [277CA and 835 ERA responses](/healthcare/submit-claim-attachments#payer-responses).
#### SFTP
SFTP submission is ideal if you have attachments that are larger than 6MB. We recommend limiting attachments to 64MB each, but some payers may have different size requirements. When in doubt, check the payer's documentation to determine their specific limits.
Submit an 837 professional or dental claim to the payer through [Stedi SFTP](/healthcare/submit-claims-sftp-connection).
You must include [specific elements](#reference-attachments-in-a-claim) in either `Loop 2300` or `Loop 2400` (professional claims only) to identify the attachment. These elements are `PWK01`, `PWK02`, and `PWK06`.
Submit a 275 claim attachment to the payer through [Stedi SFTP](/healthcare/submit-claims-sftp-connection).
You must submit a payer identifier in `Loop 1000A NM109` so Stedi can route the attachment to the correct payer. This identifier **must** be a payer ID or payer ID alias listed in the [Payer Network](https://www.stedi.com/healthcare/network). For example, you could use `60054`, `HPQRS`, `AETNA`, or any other listed payer ID alias for Aetna.
Once received, the payer processes the claim and attachment together, and sends back [277CA and 835 ERA responses](/healthcare/submit-claim-attachments#payer-responses).
## Reference attachments in a claim
To submit an unsolicited claim attachment, you must submit a claim that references the attachment(s) in the appropriate location.
### Attachment level
You can specify attachments that relate to the entire claim or to a specific service line.
* **Entire claim:** For professional and dental claims, you can specify claim-level attachments in the `claimInformation.claimSupplementalInformation.reportInformation` object or the `claimInformation.claimSupplementalInformation.reportInformations[]` array (multiple attachments). This object corresponds to segment `PWK` in `Loop 2300`.
API reference docs: [professional](/api-reference/healthcare/post-healthcare-claims#body.claimInformation.claimSupplementalInformation.reportInformation) | [dental](/api-reference/healthcare/post-healthcare-dental-claims#body.claimInformation.claimSupplementalInformation.reportInformation)
* **Service line:** For professional claims, you can specify service line attachments in the `claimInformation.serviceLines.serviceLineSupplementalInformation` object array. This object corresponds to segment `PWK` in `Loop 2400`.
API reference docs: [professional](/api-reference/healthcare/post-healthcare-claims#body.claimInformation.serviceLines.serviceLineSupplementalInformation)
### Required properties
Both claim and service line attachments require the following properties to inform the payer that an attachment will follow the claim submission.
| JSON property | X12 EDI | Description |
| ---------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `attachmentReportTypeCode` | `PWK01` | This code identifies the type of report or document you plan to submit as an attachment. Visit [Code lists](/healthcare/claims-code-lists#attachment-report-type-codes) for a complete list of valid codes. |
| `attachmentTransmissionCode` | `PWK02` | Set to `EL` when submitting attachments through Stedi. This property indicates the attachment will be sent in a separate, electronic 275 transaction. |
You must also include **one** of the following properties, depending on your use case.
| JSON property | X12 EDI | Description |
| ------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `attachmentControlNumber` | `PWK06` | A unique identifier for the attachment. The payer uses this value to match the attachment to the claim. We recommend using a ULID or UUID of up to 50 characters.- X12 EDI submissions: This property is **required**.
- JSON submissions: Only include this property when you aren't submitting the attachment file through Stedi's API. For example, you submitted the attachment directly through a payer's portal.
|
| `attachmentId` | - | The attachment ID you received in the [Create Claim Attachment (275) JSON](/api-reference/healthcare/post-healthcare-create-claim-attachment) response. It tells Stedi which file to use when generating the 275 transaction for the payer. This property is **required** if you're submitting attachments through a JSON endpoint. |
## Solicited vs. unsolicited attachments
There are two types of claim attachments:
* **Solicited:** The payer requests attachments for a submitted claim in a Request for Additional Information (277 RFA) transaction. In these cases, you must submit the attachment(s) in a separate 275 transaction that references the 277 RFA.
* **Unsolicited:** The provider proactively sends attachments at their discretion without a prior request from the payer. In these cases, you must [reference the attachment(s) in the claim submission](/healthcare/submit-claim-attachments#reference-attachments-in-a-claim).
You can only submit unsolicited claim attachments through Stedi APIs and SFTP. Check the [Payer Network](https://www.stedi.com/healthcare/network?query=eyIyNzAiOnt9LCIyNzYiOnt9LCI4MzUiOnt9LCI4MzdQIjp7fSwiODM3SSI6e30sIjgzN0QiOnt9LCJDT0IiOnt9LCIyNzVTIjp7ImlzU3VwcG9ydGVkIjp0cnVlfSwiMjc1VSI6eyJpc1N1cHBvcnRlZCI6dHJ1ZX19\&page=0) to determine which payers support attachments.
## Payer responses
The payer processes claims and claim attachments together. When you submit a claim attachment, you'll receive the same [277CA and 835 ERA responses](/healthcare/receive-claim-responses#response-types) for the claim as you would for a regular claim submission.
If a claim is rejected, pended, or denied due to issues with attachments, you'll likely receive error codes in the 277CA response that indicate the issue. However, the exact error codes used depend on the payer's system and how they handle attachments.
## Concurrency limit
Claim attachment endpoints share a concurrency pool with other claim endpoints. For more information, visit [Concurrency limits](/api-reference#concurrency-limits).
# Submit claims through SFTP
Source: https://www.stedi.com/docs/healthcare/submit-claims-sftp-connection
***
title: Submit claims through SFTP
sidebarTitle: SFTP submission
-----------------------------
You can use Stedi's fully-managed SFTP server to submit claims - including 275 claim attachments - to payers and retrieve responses without calling Stedi APIs.
You must submit claims and attachments in X12 EDI format, and Stedi returns claim responses through the SFTP connection in X12 EDI format. This makes Stedi SFTP a good option if you have an existing system that generates X12 EDI files and you want to send them through Stedi without completing an API integration.
## How SFTP connections work
Use the following process to submit claims to Stedi:
1. Create SFTP users through the [SFTP setup](https://portal.stedi.com/app/settings/sftp) page in your account. You'll use these credentials to connect to Stedi's SFTP server.
2. Connect to Stedi's server and drop X12 EDI claim files into the `to-stedi` directory.
3. Stedi automatically validates the claim data and uses the Interchange Usage Indicator field (`T` or `P`) to determine whether each file contains a test or a production claim. If there are no validation errors, Stedi routes your claims to the test or production clearinghouse accordingly.
4. Stedi places claim responses - 277CA claim acknowledgments and 835 Electronic Remittance Advice (ERAs) - into the `from-stedi` directory in X12 EDI format. You can retrieve these responses from the directory at your preferred cadence without setting up webhooks or calling Stedi APIs.
Stedi shows all claims and claim responses sent through the SFTP connection on the [Files](https://portal.stedi.com/app/core/file-executions) and [Transactions](https://portal.stedi.com/app/core/transactions) pages in the UI. This allows you to review your claim submissions, quickly find related responses, and download transaction data.
## Before sending claims
You may need to complete the following steps before sending claims.
### Transaction enrollment
All payers require providers to complete an enrollment process before they can start receiving 835 ERAs. Some payers also require enrollment before allowing providers to submit claims.
The [Stedi Payer Network](https://www.stedi.com/healthcare/network) lists which payers require transaction enrollment. Visit [Transaction enrollment](/healthcare/transaction-enrollment) for details about the transaction enrollment process.
### Coordination of benefits check
We recommend running a coordination of benefits (COB) check to ensure you submit claims to the correct payer. COB checks can help you determine:
* If a patient is covered by more than one health plan
* Whether coverage overlap requires coordination of benefits
* Each payer’s responsibility for payment (primacy) in coordination of benefits scenarios
Visit [Coordination of benefits (COB) checks](/healthcare/coordination-of-benefits) for more information.
## Create SFTP users
Go to the [SFTP setup](https://portal.stedi.com/app/settings/sftp) page in your account settings to create SFTP users.
You can create either test or production users.
* Test users can only send claims with the Usage Indicator Code set to `T` (test). These claims are only sent to Stedi's test clearinghouse and not to the payer. Note that you will receive a 277 Claim Acknowledgment for test claims, but you will not receive an 835 ERA.
* Production users can only send claims with the Usage Indicator Code set to `P` (production). These claims are sent through Stedi's production clearinghouse to the payer.
## Connect to Stedi's server
Use your user credentials to connect to Stedi's SFTP server at `transfer.us.stedi.com` using Port 22.
### Static IPs
You can use these static IP addresses to allowlist Stedi's server:
`18.119.51.218` and `18.206.132.233`
## Format X12 EDI files
You must drop claims and claim attachments into the `to-stedi` directory in X12 EDI format. Stedi validates the claims and routes them to the appropriate clearinghouse based on the `ISA15` Interchange Usage Indicator element.
### 837 claims
Claims must adhere to the following X12 HIPAA claim specifications:
* [837 Claim: Professional (X222A1)](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-professional-x222a1/01HR60MDFAGCSEJNKY8J38867Y)
* [837 Claim: Institutional (X223A2)](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-institutional-x223a2/01JBHW2YXMN2F9KXK2PS0BFP9F)
* [837 Claim: Dental (X224A2)](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-dental-x224a2/01JCJZ46AEK835RYV1BXQNBPK8)
We recommend submitting one claim per file to make troubleshooting easier. However, an EDI Interchange can contain multiple transactions, so you can submit multiple claims within a single file if needed. Regardless of how many claims you submit in a file, Stedi processes each claim individually and returns each claim response as a separate file.
#### Payer ID
You must submit a payer identifier in `Loop 2010BB` (Payer Name) `NM109` so Stedi can route your claim to the correct payer. This identifier **must** be a payer ID or payer ID alias listed in the [Payer Network](https://www.stedi.com/healthcare/network?page=0). For example, you could use `60054`, `HPQRS`, `AETNA`, or any other listed payer ID alias for Aetna.
### 275 claim attachments
Claim attachments must adhere to the [275 Patient Information](https://portal.stedi.com/app/guides/view/hipaa/patient-information-x210/01HQ4HZ8ZBY2CZGPCVVM8JTK22) X12 HIPAA specification.
Before you can submit an attachment, you must first submit a claim that references the attachment(s) in the appropriate location. Visit [Claim attachments](/healthcare/submit-claim-attachments) for complete instructions.
We recommend limiting attachments to 64MB each, but some payers may have different size requirements. When in doubt, check the payer's documentation to determine their specific limits.
This limit is per attachment file - you can submit multiple attachment files in each 275 transaction.
### Envelope and header
You can submit transactions with any values in the `ISA` and `GS` envelope, as long as they conform to the X12 EDI specification.
However, you must set `ST03` to the appropriate value for the transaction type:
* 837P professional claims: `005010X222A1`
* 837I institutional claims: `005010X223A2`
* 837D dental claims: `005010X224A2`
* 275 claim attachments: `005010X210`
If your system requires you to send unique values in the `ISA` and `GS` envelope, you can find suggested configurations for each transaction type on the [SFTP setup page](https://portal.stedi.com/app/settings/sftp) under **ISA settings**.
## Set up webhooks (recommended)
Stedi emits events when it processes claims and claim responses.
* **File delivered:** Emitted when Stedi successfully processes your claim and delivers it to our connection with the payer. Note that this event doesn’t indicate whether the payer received the claim or whether they have accepted or rejected it.
* **File failed:** Emitted when Stedi cannot deliver the claim to the payer due to validation errors in the X12 EDI claim data. You must fix the errors and resubmit the claim.
* **Transaction processed:** Emitted when Stedi successfully receives and processes a payer or intermediary clearinghouse response, such as an 835 ERA. These events are also emitted when Stedi successfully processes claims you submit through the SFTP connection.
We recommend setting up [webhooks](/healthcare/configure-webhooks) for at least file failed events so you can monitor for claim submission errors. Otherwise, your claim submissions may silently fail, and it will be much more difficult to troubleshoot issues.
## Send claims and retrieve responses
You can drop claims into the `to-stedi` directory. Stedi automatically validates the claim data and then routes each claim to the appropriate clearinghouse (test or production). Stedi deletes files from the `to-stedi` directory after processing them to avoid duplicate claim submissions.
After submitting a claim, you may receive [277 Claim Acknowledgment](https://portal.stedi.com/app/guides/view/hipaa/claim-acknowledgment-x214/01HACJ4MNFWR3GV3BCVAMG04PK) and the [835 Health Care Claim Payment/Advice](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-paymentadvice-x221a1/01GRYB6DS30MGXWBPFZCM3695E) (ERA) responses in X12 EDI format. You can retrieve these claim responses at your preferred cadence from the `from-stedi` directory.
### 277CA claim acknowledgment
The 277CA indicates whether the claim was accepted or rejected and (if relevant) the reasons for rejection. Though it can contain claim status information, the 277CA is different from the synchronous 277 claim status response you receive after submitting a [real-time claim status](/api-reference/healthcare/post-healthcare-claim-status) request.
You may receive multiple separate 277CAs for each claim you submit.
* You'll receive the first 277CA from Stedi within about 30 minutes of submitting the claim. This 277CA may contain rejection message(s) and warnings, if applicable.
* You may receive additional 277CAs from intermediary clearinghouses.
* You'll receive one or more 277CAs from the payer. Typically, there is one 277CA that indicates receipt of the claim and a second 277CA that contains summary counts of transactions received, information about accepted transactions, and details for rejected transactions.
Each 277CA typically correlates to one 837 claim. However, some payers may send a single 277CA that [references multiple claims](/healthcare/receive-claim-responses#correlate-277ca).
#### Determine sender
You can determine whether a 277CA is from a clearinghouse or the payer from the [`transactions.payers` array](https://www.stedi.com/docs/api-reference/healthcare/get-healthcare-reports-277#response-transactions-payers) in the report. The `organizationName` property contains the name of the sender (for example, `CIGNA`) and the `identityIdentifierCodeValue` contains either `Clearinghouse` or `Payer`.
This information is also available at the top of the 277CA's [transaction details page](https://portal.stedi.com/app/core/transactions) in the Stedi portal.
### 835 Electronic Remittance Advice (ERA)
The ERA contains details about payments for specific services and explanations for any adjustments or denials. The payer only sends ERAs for accepted claims. If a claim is rejected in a 277CA, there's no adjudication or payment information to report.
Processing ERAs always requires [transaction enrollment](/healthcare/transaction-enrollment) with the payer.
#### Duplicate ERAs
Payers typically only send one ERA per claim. However, they may occasionally retransmit another identical 835 ERA, so you should have logic in place to handle these duplicates.
You can assume an ERA is a duplicate if the Check or EFT Trace Number is the same. This is the `transactions[].paymentAndRemitReassociationDetails.checkOrEFTTraceNumber` property in a processed 835 ERA from Stedi. In X12 EDI, this is available in segment `TRN` (Reassociation Trace Number), element `TRN02` (Check or EFT Trace Number).
## Correlate responses with claim
You can use the following identifiers from the original claim to correlate the 277CA and 835 ERA responses.
### Entire claim
Use `Loop 2300 CLM01` (Patient Control Number) from the original claim, if provided.
* In the 277CA, this number is returned as `Loop 2200D TRN02` (Patient Control Number).
Some payers batch acknowledgments for multiple claims into a single 277CA. This is more likely if you submitted multiple claims within a single 837 claim envelope. In these cases, the 277CA will contain multiple iterations of `Loop 2200D` (Claim Status Tracking Number). You can use each `TRN02` (Patient Control Number) value in the 277CA to correlate it with the original claim.
* In the 835 ERA, this number is returned as `Loop 2100 CLP01` (Patient Control Number).
### Specific service lines
Use `Loop 2400 REF02` (Line Item Control Number) from the original claim, if provided.
Location in responses:
* In the 277CA, this number is sometimes returned as `Loop 2220D REF02` (Line Item Control Number), but not always. This is because a 277CA only contains `Loop 2220D` (Service Line Information) when the claim was rejected because of issues with the information provided for the service line.
* In the 835 ERA this number is returned as `Loop 2110 REF02` (Line Item Control Number).
# Submit dental claims
Source: https://www.stedi.com/docs/healthcare/submit-dental-claims
***
title: Submit dental claims
sidebarTitle: "Dental claims"
-----------------------------
You can send 837D dental claims to payers through the Stedi API or SFTP connection.
Once you send a claim, Stedi automatically receives and processes 277CA claim acknowledgment and 835 Electronic Remittance Advice (ERA) responses.
## Before sending claims
You may need to complete the following steps before sending claims.
### Transaction enrollment
All payers require providers to complete an enrollment process before they can start receiving 835 ERAs. Some payers also require enrollment before allowing providers to submit claims.
The [Stedi Payer Network](https://www.stedi.com/healthcare/network) lists which payers require transaction enrollment. Visit [Transaction enrollment](/healthcare/transaction-enrollment) for details about the transaction enrollment process.
### Coordination of benefits check
We recommend running a coordination of benefits (COB) check to ensure you submit claims to the correct payer. COB checks can help you determine:
* If a patient is covered by more than one health plan
* Whether coverage overlap requires coordination of benefits
* Each payer’s responsibility for payment (primacy) in coordination of benefits scenarios
Visit [Coordination of benefits (COB) checks](/healthcare/coordination-of-benefits) for more information.
## SFTP submission
You can use Stedi’s fully-managed SFTP server to submit claims to to payers and retrieve claim responses without calling Stedi’s APIs.
You must submit claims in X12 EDI format, and Stedi returns claim responses through the SFTP connection in X12 EDI format. This makes Stedi SFTP a good option if you have an existing system that generates X12 EDI files and you want to send them through the Stedi clearinghouse without completing an API integration. Visit [SFTP connection](/healthcare/submit-claims-sftp-connection) for more information.
## API submission
Call one of the following endpoints to submit 837D dental claims:
* [Dental Claims](/api-reference/healthcare/post-healthcare-dental-claims) to send requests in JSON
* [Dental Claims Raw X12](/api-reference/healthcare/post-healthcare-dental-claims-raw-x12) to send requests in X12 EDI
Both endpoints return a synchronous response from Stedi in JSON format. Later, the payer will respond with a 277CA claim acknowledgment.
### Headers
When constructing the request, you must include the following information in HTTP headers:
* **`Authorization`:** [Generate an API key](https://portal.stedi.com/app/settings/api-keys) to use for authentication.
* **`Content-Type`:** Set to `application/json`.
### Body - JSON
The information you submit for a claim depends on your use case. Refer to the [Dental Claims](/api-reference/healthcare/post-healthcare-dental-claims) endpoint for a complete list of properties. However, all claims require the following high-level information:
\| Information | Description |
\| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
\| `tradingPartnerServiceId` | This is the payer ID. Visit the [Payer Network](https://www.stedi.com/healthcare/network) for a complete list. |
\| `tradingPartnerName` | This is the payer's business name, like Cigna or Aetna. |
\| `submitter` object | Information about the entity submitting the claim. This can be either an individual or an organization, such as a doctor, hospital, or insurance company. |
\| `receiver` object | Information about the payer, such as an insurance company or government agency. |
\| `subscriber` and/or `dependent` objects | Information about the patient who received the medical services. Note that if a dependent has their own, unique member ID for their health plan, you should submit their information in the `subscriber` object and omit the `dependent` object from the request. You can check whether the dependent has a unique member ID by submitting an [Eligibility Check](/api-reference/healthcare/post-healthcare-eligibility) to the payer for the dependent. The payer will return the member ID in the `dependents.memberId` field, if present. |
\| `claimInformation` object | Information about the claim, such as the patient control number, claim charge amount, and place of service code. It also includes information about each individual service line included in the claim. |
\| `billing` object | Information about the billing provider, such as the [NPI](/healthcare/national-provider-identifier), taxonomy code, and organization name. |
#### Service line identification
A claim can contain multiple service lines. Since the payer may accept, reject, or pay a subset of those lines, you can receive an 835 ERA that references a `patientControlNumber`, but only pertains to some of the service lines.
However, the `claimInformation.serviceLines.providerControlNumber` serves as a unique identifier for each service line in your claim submission. This value appears in the 277CA claim acknowledgment and 835 ERA as the `lineItemControlNumber`, allowing you to correlate these responses to specific service lines from the original claim. If you don't set the `providerControlNumber` for a service line, Stedi uses a random UUID.
Stedi returns service line identifiers in the `claimReference.serviceLines` object of the synchronous API response.
#### Conditional requirements
Note that objects marked as **required** are required for all requests, while others are conditionally required depending on the circumstances. When you include a conditionally required object, you must include all of its required properties.
For example, you must always include the `subscriber` object in your request, but you only need to include the `supervising` object when the rendering provider is supervised by a physician.
### Body - X12 EDI
You must send a payload in [837 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-dental-x224a3/01GRYB6G91ZX6R1XAFGBMRTBBW).
Note the following requirements and behavior when sending dental claims through the raw X12 endpoint.
#### Envelope and header
Stedi generates its own `ISA` and `GS` headers and `IEA` and `GE` trailers before sending your claim to the payer. You can submit your claim to Stedi with any values in these segments, as long as they conform to the X12 EDI specification.
However, you must set `ST03` (Implementation Guide Version Name) to `005010X224A2`.
#### Payer ID
You must submit a payer identifier in `Loop 2010BB` (Payer Name) `NM109` so Stedi can route your claim to the correct payer. This identifier **must** be a payer ID or payer ID alias listed in the [Payer Network](https://www.stedi.com/healthcare/network?page=0). For example, you could use `60054`, `HPQRS`, `AETNA`, or any other listed payer ID alias for Aetna.
#### `CLM01` (Patient Control Number)
We **strongly recommend** submitting a unique value for `Loop 2300` (Claim Information) `CLM01` (Patient Control Number). The payer returns this value in related transactions, such as the 277CA and 835 ERA, so you can correlate responses and real-time claim status checks with the original claim.
We recommend using only alphanumeric characters and generating unique values that are the shortest possible length. Stedi accepts any valid value, but some payers replace non-alphanumeric characters and truncate shorter than the official 20-character limit. When this happens, the payer returns a different identifier in responses than the one you originally sent, making it more difficult to correlate the claim and perform real-time claim status checks.
#### Service line identification
A claim can contain multiple service lines. Since the payer may accept, reject, or pay a subset of those lines, you can receive an 835 response that references a patient control number, but only pertains to some of the service lines.
However, the line item control number serves as a unique identifier for each service line in your claim submission.
* You can set the line item control number in `Loop 2400 REF02`, when `REF01` = `6R`. The line item control number appears in the 277CA and 835 ERA responses as the `lineItemControlNumber`, allowing you to correlate these responses to specific service lines from the original claim.
* If you don’t set the line item control number for a service line, Stedi uses a ULID.
### Character restrictions
Only use the X12 Basic and Extended character sets in request data. Using characters outside these sets may cause validation and HTTP `400` errors.
The X12 Basic character set includes uppercase letters, digits, space, and some special characters. Lowercase letters and special language characters like `ñ` are not included.
The following special characters are included:

The Extended character set includes the characters listed in Basic, plus lowercase letters and additional special characters, such as `@`.
The following additional special characters are included:

In addition, the following characters are reserved for delimiters in the final X12 EDI transaction to the payer: `~`, `*`, `:`, and `^`. X12 doesn’t support using escape sequences to represent delimiters or special characters. Stedi returns a `400` error if you use these restricted characters improperly.
* **JSON endpoint:** Don’t include delimiter characters anywhere in your request data.
* **Raw X12 endpoint:** You can use these characters as delimiters, but not in the body of the request data.
### Sample request and response
The following examples send a dental claim. The response shape is the same for both the JSON and X12 EDI endpoints. It contains summary information from Stedi about the claim submission and whether it was successful.
{/* schema:DentalClaimsSubmissionRequestContent */}
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/dental-claims/submission \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"usageIndicator": "T",
"tradingPartnerServiceId": "52133",
"tradingPartnerName": "United HealthCare Dental",
"subscriber": {
"paymentResponsibilityLevelCode": "P",
"memberId": "123412345",
"firstName": "John",
"lastName": "Doe",
"groupNumber": "1234567890",
"gender": "F",
"address": {
"address1": "1234 Some St",
"city": "Buckeye",
"state": "AZ",
"postalCode": "85326"
},
"dateOfBirth": "20180615"
},
"submitter": {
"organizationName": "ABA Inc",
"submitterIdentification": "",
"contactInformation": {
"phoneNumber": "3131234567",
"name": "BILLING DEPARTMENT"
}
},
"rendering": {
"npi": "1999999992",
"taxonomyCode": "106S00000X",
"providerType": "RenderingProvider",
"lastName": "Doe",
"firstName": "Jane"
},
"receiver": {
"organizationName": "United HealthCare Dental"
},
"payerAddress": {
"address1": "PO Box 7000",
"city": "Camden",
"state": "SC",
"postalCode": "29000"
},
"claimInformation": {
"signatureIndicator": "Y",
"toothStatus": [
{
"toothNumber": "3",
"toothStatusCode": "E"
}
],
"serviceLines": [
{
"serviceDate": "20230428",
"renderingProvider": {
"npi": "1999999992",
"taxonomyCode": "122300000X",
"lastName": "Doe",
"firstName": "Jane"
},
"providerControlNumber": "a0UDo000000dd2dMAA",
"dentalService": {
"procedureCode": "D7140",
"lineItemChargeAmount": "832.00",
"placeOfServiceCode": "12",
"oralCavityDesignation": [
"1",
"2"
],
"prosthesisCrownOrInlayCode": "I",
"procedureCount": 2,
"compositeDiagnosisCodePointers": {
"diagnosisCodePointers": [
"1"
]
}
},
"teethInformation": [
{
"toothCode": "3",
"toothSurfaceCodes": [
"M",
"O"
]
}
]
}
],
"serviceFacilityLocation": {
"phoneNumber": "3131234567",
"organizationName": "ABA Inc",
"npi": "1999999992",
"address": {
"address1": "ABA Inc 123 Some St",
"city": "Denver",
"state": "CO",
"postalCode": "802383100"
}
},
"releaseInformationCode": "Y",
"planParticipationCode": "A",
"placeOfServiceCode": "12",
"patientControlNumber": "",
"healthCareCodeInformation": [
{
"diagnosisTypeCode": "ABK",
"diagnosisCode": "K081"
}
],
"claimSupplementalInformation": {
"priorAuthorizationNumber": "20231010012345678"
},
"claimFrequencyCode": "1",
"claimFilingCode": "FI",
"claimChargeAmount": "832.00",
"benefitsAssignmentCertificationIndicator": "Y"
},
"billing": {
"taxonomyCode": "106S00000X",
"providerType": "BillingProvider",
"organizationName": "ABA Inc",
"npi": "1999999992",
"employerId": "123456789",
"contactInformation": {
"phoneNumber": "3134893157",
"name": "ABA Inc"
},
"address": {
"address1": "ABA Inc 123 Some St",
"city": "Denver",
"state": "CO",
"postalCode": "802383000"
}
}
}'
```
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/dental-claims/raw-x12-submission \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"x12": "ISA*00* *00* *ZZ*001690149382 *ZZ*STEDITEST *240630*0847*^*00501*000000001*0*T*>~GS*HC*001690149382*STEDITEST*20240630*084744*000000001*X*005010X224A2~ST*837*3456*005010X224A2~BHT*0019*00*0123*20061123*1023*CH~NM1*41*2*PREMIER BILLING SERVICE*****46*TGJ23~PER*IC*JERRY*TE*7176149999~NM1*40*2*INSURANCE COMPANY XYZ*****46*66783JJT~HL*1**20*1~NM1*85*2*DENTAL ASSOCIATES*****XX*1999999992~N3*234 SEAWAY ST~N4*MIAMI*FL*33111~REF*EI*587654321~HL*2*1*22*1~SBR*P********CI~NM1*IL*1*SMITH*JANE****MI*111223333~NM1*PR*2*INSURANCE COMPANY XYZ*****PI*66783JJT~HL*3*2*23*0~PAT*19~NM1*QC*1*SMITH*TED~N3*236 N MAIN ST~N4*MIAMI*FL*33413~DMG*D8*19920501*M~CLM*26403774*150***11>B>1*Y*A*Y*I~DTP*472*D8*20061029~REF*D9*17312345600006351~NM1*82*1*DOE*JOHN****XX*1999999992~PRV*PE*PXC*1223G0001X~LX*1~SV3*AD>D2150*100****1~TOO*JP*12*M>O~LX*2~SV3*AD>D1110*50****1~SE*31*3456~GE*1*000000001~IEA*1*000000001~"
}'
```
{/* schema:DentalClaimsSubmissionResponseContent */}
```json
{
"status": "SUCCESS",
"controlNumber": "1",
"tradingPartnerServiceId": "52133",
"claimReference": {
"correlationId": "01JDQMX92Q1T561BH8NKX750TQ",
"patientControlNumber": "0U1LBRS4",
"timeOfResponse": "2024-11-27T20:27:27.077Z",
"payerID": "52133",
"formatVersion": "5010",
"rhclaimNumber": "01JDQMX92Q1T561BH8NKX750TQ",
"serviceLines": [
{
"lineItemControlNumber": "a0UDo000000dd2dMAA"
}
]
},
"httpStatusCode": "200 OK",
"meta": {
"traceId": "9b491769-052e-4738-93d6-e0b5f6d83f53"
},
"payer": {
"payerName": "United HealthCare Dental",
"payerID": "52133"
}
}
```
### Test claims
All claims you submit through the API are sent to the payer as production claims unless you explicitly designate them as test data.
To send test claims:
* **JSON endpoint:** Set the `usageIndicator` property in the test claim body to `T`.
* **X12 EDI endpoint:** Set `ISA15` (Interchange Usage Indicator) to `T` (Test Data) instead of `P` (Production Data).
When you send a test claim, Stedi does not send it to the payer. Instead, it processes the claim as if it were sent to the payer and returns a response indicating whether the claim was successfully processed.
Designating a claim as test data allows you to filter for test claims on the [Transactions](https://portal.stedi.com/app/core/transactions) page in the Stedi portal.
Note that you will receive a 277CA claim acknowledgment in response to test claims, allowing you to test your workflow end to end, but you will not receive a test 835 ERA response.
### Concurrency limit
Dental claim submission endpoints share a concurrency pool with other claim endpoints. For more information, visit [Concurrency limits](/api-reference#concurrency-limits).
### Recommended API clients
You may want to use an API client to make testing and debugging easier.
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.
Visit [API clients](/api-reference#api-clients) for a list of recommended clients you can use instead.
## View submitted claims
You can view the files that Stedi sends and receives in the [Files](https://portal.stedi.com/app/core/file-executions) page of the Stedi portal.
On the [Transactions](https://portal.stedi.com/app/core/transactions) page, you can review and filter claims by **Usage** - production or test. Click any claim submission to review its details, including the full request and response payload and processing events.
## Cancel or resubmit claims
You may need to resubmit claims for several reasons, including changes to the patient's coverage, errors in the original claim's information, or appealing a denied claim. You may also need to cancel duplicate claims or claims that were submitted in error.
You can cancel and revise claims by resubmitting them through Stedi portal, API, or SFTP.
### Manual resubmission
To manually resubmit a claim through the Stedi portal:
1. Go to the [Transactions](https://portal.stedi.com/app/healthcare/transactions) page in your Stedi account and click the claim you want to resubmit.
2. Click **Edit and resubmit**. Stedi opens the claim in an interactive inspector, with the X12 EDI on the left and the EDI specification on the right.
3. Make any necessary changes to the claim EDI, then click **Review and submit**. Stedi shows a comparison of the original claim and the new claim containing your changes.
4. Click **Resubmit claim** to send the updated claim to the payer.
### Claim Frequency Code
Set the Claim Frequency Code to one of the following values. This is the `claimInformation.claimFrequencyCode` property in JSON and the `Loop 2300 CLM05-03` (Claim Frequency Code) component in X12 EDI.
* **Resubmit to Stedi or another payer:** Set to `1` - Admit thru Discharge Claim. Either Stedi rejected the claim due to validation errors, or you're resubmitting the claim to a different payer for the first time. In either case, the payer hasn't yet processed the claim.
* **Correct or replace claims:** Set to `7` - Replacement of Prior Claim. In this case, the payer processed the original claim.
* **Cancel claims:** Set to `8` - Void/Cancel of Prior Claim.
### Payer Claim Control Number
When correcting, replacing, or canceling claims, you should include the Payer Claim Control Number (sometimes called the ICN) from the original claim for identification. In JSON, this is the `claimInformation.claimSupplementalInformation.claimControlNumber` property. In X12 EDI, this is `Loop 2300 REF02`, where `REF01` = `F8` (Original Reference Number).
* The Payer Claim Control Number is different from the `claimInformation.patientControlNumber` (`Loop 2300 CLM01`) you sent in the original claim. It's also different from the Stedi-generated `controlNumber` returned in the API response.
* You can retrieve the Payer Claim Control Number from one of the payer's 277CA claim acknowledgments in the `transactions.payers.claimStatusTransactions.claimStatusDetails.patientClaimStatusDetails.claims.claimStatus.tradingPartnerClaimNumber` property.
### Patient Control Number
When correcting or replacing claims, we also recommend setting a new, unique Patient Control Number. This is the `claimInformation.patientControlNumber` property in JSON and `Loop 2300 CLM01` in X12 EDI. The payer includes this value in their 835 ERA, allowing you to easily correlate that response with your resubmission.
## 275 claim attachments
If the claim requires attachments, you must include additional details about the attachments in the [`claimInformation.claimSupplementalInformation.reportInformation`](/api-reference/healthcare/post-healthcare-dental-claims#body.claimInformation.claimSupplementalInformation.reportInformation) object or the [`claimInformation.claimSupplementalInformation.reportInformations`](/api-reference/healthcare/post-healthcare-dental-claims#body.claimInformation.claimSupplementalInformation.reportInformations) array (multiple attachments).
Visit [Claim attachments](/healthcare/submit-claim-attachments) for complete instructions.
## Submit claims to a secondary or tertiary payer
In [coordination of benefits (COB)](/healthcare/coordination-of-benefits) scenarios, you'll need to submit a claim to multiple payers.
You must set the `subscriber.paymentResponsibilityLevelCode` to either `S` (when submitting to the secondary payer) or `T` (when submitting to the tertiary payer).
You must also include the following information about how prior payers have adjudicated the claim. For example, if a patient's private insurance plan (primary payer) adjusted the requested reimbursement amount and paid for its portion of the services, you must include that information in the claim you submit to Medicare (secondary payer). You can find these details in 835 ERA responses from prior payers.
### Claim information
You must submit one `claimInformation.otherSubscriberInformation` object for each prior payer. Supply all the required properties in the object plus the following additional information:
* `claimLevelAdjustments`: Provide if the prior payer made adjustments at the claim level. Codes and their associated amounts must come from ERAs sent by the prior payers. You can find these codes in the ERA's [`transactions.detailInfo.paymentInfo.claimAdjustments`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.claimAdjustments) object.
* `medicareInpatientAdjudication` (institutional claims only): You must include this if Medicare was one of the prior payers and reported inpatient adjudication information on the ERA.
* `medicareOutpatientAdjudication`: You must include this if Medicare was one of the prior payers and reported outpatient adjudication information on the ERA.
* `otherPayerName.otherPayerAdjudicationOrPaymentDate`: The date the payer adjudicated or paid the claim. You must provide this if you aren't providing a value in the `claimInformation.serviceLines.lineAdjudicationInformation.adjudicationOrPaymentDate` property.
* `payerPaidAmount`: This is the total amount in dollars the payer paid on this claim.
### Service line information
You must submit `serviceLines.lineAdjudicationInformation` objects when the prior payers provided line-level adjudication information. Submit one object for each prior payer. For each object, you should include the following properties.
* `adjudicationOrPaymentDate`: The date the payer adjudicated or paid the claim. Don't include this if you're providing a date in the `otherPayerName.otherPayerAdjudicationOrPaymentDate` property.
* `claimAdjustmentInformation`: You can find this information in the ERA's [`transactions.detailInfo.paymentInfo.serviceLines.serviceAdjustments`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.serviceLines.serviceAdjustments) object.
* `otherPayerPrimaryIdentifier`: The identifier for the other payer. This value should match the identifier you supplied for the payer in the `claimInformation.otherSubscriberInformation.otherPayerName.otherPayerIdentifier` property.
* `procedureCode`: The adjudicated procedure code for the service line.
* `serviceIdQualifier`: A code identify the type of procedure code. Visit [Claims code lists](/healthcare/claims-code-lists#composite-medical-procedure---product-or-service-id-qualifier-codes) for a complete list.
* `serviceLinePaidAmount`: The total amount in dollars the prior payer paid on this service line.
* `paidServiceUnitCount`: The number of paid units for the service line. When paid units are not present on the remittance advice, use the original billed units.
* `remainingPatientLiability`: The amount of the service line the patient is responsible for paying.
## Claim Filing Indicator Code
The Claim Filing Indicator Code indicates how a claim was filed with a payer, such as `MC` (Medicaid) or `CI` (Commercial Insurance Co.).
Choosing the correct claim filing indicator code is important for successful claim submission. Visit the [Claims code lists](/healthcare/claims-code-lists#choosing-the-right-code) documentation for best practices for selecting the appropriate code.
# Submit institutional claims
Source: https://www.stedi.com/docs/healthcare/submit-institutional-claims
***
title: Submit institutional claims
sidebarTitle: "Institutional claims"
------------------------------------
You can send 837I institutional claims to payers through the Stedi API or SFTP connection.
Once you send a claim, Stedi automatically receives and processes 277CA claim acknowledgments and 835 Electronic Remittance Advice (ERA) responses.
## Before sending claims
You may need to complete the following steps before sending claims.
### Transaction enrollment
All payers require providers to complete an enrollment process before they can start receiving 835 ERAs. Some payers also require enrollment before allowing providers to submit claims.
The [Stedi Payer Network](https://www.stedi.com/healthcare/network) lists which payers require transaction enrollment. Visit [Transaction enrollment](/healthcare/transaction-enrollment) for details about the transaction enrollment process.
### Coordination of benefits check
We recommend running a coordination of benefits (COB) check to ensure you submit claims to the correct payer. COB checks can help you determine:
* If a patient is covered by more than one health plan
* Whether coverage overlap requires coordination of benefits
* Each payer’s responsibility for payment (primacy) in coordination of benefits scenarios
Visit [Coordination of benefits (COB) checks](/healthcare/coordination-of-benefits) for more information.
## SFTP submission
You can use Stedi’s fully-managed SFTP server to submit claims to to payers and retrieve claim responses without calling Stedi’s APIs.
You must submit claims in X12 EDI format, and Stedi returns claim responses through the SFTP connection in X12 EDI format. This makes Stedi SFTP a good option if you have an existing system that generates X12 EDI files and you want to send them through the Stedi clearinghouse without completing an API integration. Visit [SFTP connection](/healthcare/submit-claims-sftp-connection) for more information.
## API submission
Call one of the following endpoints to submit 837I institutional claims:
* [Institutional Claims](/api-reference/healthcare/post-healthcare-institutional-claims) to send requests in JSON
* [Institutional Claims Raw X12](/api-reference/healthcare/post-healthcare-institutional-claims-raw-x12) to send requests in X12 EDI
Both endpoints return a synchronous response from Stedi in JSON format. Later, the payer will respond with a 277CA claim acknowledgment.
### Headers
When constructing the request, you must include the following information in HTTP headers:
* **`Authorization`:** [Generate an API key](https://portal.stedi.com/app/settings/api-keys) to use for authentication.
* **`Content-Type`:** Set to `application/json`.
### Body - JSON
The information you submit for a claim depends on your use case. Refer to the [Institutional Claims](/api-reference/healthcare/post-healthcare-institutional-claims) endpoint for a complete list of properties. However, all claims require the following high-level information:
|Information | Description|
\|------------|------------|
\| `tradingPartnerServiceId` | This is the payer ID. Visit the [Payer Network](https://www.stedi.com/healthcare/network) for a complete list. | |
\| `submitter` object | Information about the entity submitting the claim. This is an organization, such as a hospital or other treatment center. |
\| `receiver` object | Information about the entity responsible for the payment of the claim, such as an insurance company or government agency. |
\| `subscriber` and/or `dependent` objects | Information about the patient who received the medical services. Note that if a dependent has their own, unique member ID for their health plan, you should submit their information in the `subscriber` object and omit the `dependent` object from the request. You can check whether the dependent has a unique member ID by submitting an [Eligibility Check](/api-reference/healthcare/post-healthcare-eligibility) to the payer for the dependent. The payer will return the member ID in the `dependents.memberId` field, if present. |
\| `claimInformation` object | Information about the claim, such as the claim filing code (identifies the type of claim), claim charge amount, and place of service code. It also includes information about each individual service line included in the claim. |
\| Billing provider | You **must** supply information about the billing provider in either the `providers` or `billing` object. This includes the provider's [NPI](/healthcare/national-provider-identifier), name, and other information. |
#### Service line identification
A claim can contain multiple service lines. Since the payer may accept, reject, or pay a subset of those lines, you can receive an 835 ERA that references a `patientControlNumber`, but only pertains to some of the service lines.
However, the `claimInformation.serviceLines.lineItemControlNumber` serves as a unique identifier for each service line in your claim submission. This value appears in the 277CA claim acknowledgment and 835 ERA as the `lineItemControlNumber`, allowing you to correlate these responses to specific service lines from the original claim. We strongly recommend setting the `lineItemControlNumber` to a ULID or other unique identifier for each service line. We recommend using a ULID instead of a UUID because the property has a max of 30 characters.
#### Conditional requirements
Note that objects marked as **required** are required for all requests, while others are conditionally required depending on the circumstances. When you include a conditionally required object, you must include all of its required properties.
For example, you must always include the `subscriber` object in your request, but you only need to include the `supervising` object when the rendering provider is supervised by a physician.
## Body - X12 EDI
You must send a payload in [837 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-institutional-x223a2/01JBHW2YXMN2F9KXK2PS0BFP9F).
Note the following requirements and behavior when sending institutional claims through the raw X12 endpoint.
#### Envelope and header
Stedi generates its own `ISA` and `GS` headers and `IEA` and `GE` trailers before sending your claim to the payer. You can submit your claim to Stedi with any values in these segments, as long as they conform to the X12 EDI specification.
However, you must set `ST03` (Version, Release, or Industry Identifier) to `005010X223A2`.
#### Payer ID
You must submit a payer identifier in `Loop 2010BB` (Payer Name) `NM109` so Stedi can route your claim to the correct payer. This identifier **must** be a payer ID or payer ID alias listed in the [Payer Network](https://www.stedi.com/healthcare/network?page=0). For example, you could use `60054`, `HPQRS`, `AETNA`, or any other listed payer ID alias for Aetna.
#### `CLM01` (Patient Control Number)
We **strongly recommend** submitting a unique value for `Loop 2300` (Claim Information) `CLM01` (Patient Control Number). The payer returns this value in related transactions, such as the 277CA and 835 ERA, so you can correlate responses and real-time claim status checks with the original claim.
We recommend using only alphanumeric characters and generating unique values that are the shortest possible length. Stedi accepts any valid value, but some payers replace non-alphanumeric characters and truncate shorter than the official 20-character limit. When this happens, the payer returns a different identifier in responses than the one you originally sent, making it more difficult to correlate the claim and perform real-time claim status checks.
#### Service line identification
A claim can contain multiple service lines. Since the payer may accept, reject, or pay a subset of those lines, you can receive an 835 response that references a patient control number, but only pertains to some of the service lines.
However, the line item control number serves as a unique identifier for each service line in your claim submission.
* You can set the line item control number in `Loop 2400 REF02`, when `REF01` = `6R`. The line item control number appears in the 277CA and 835 ERA responses as the `lineItemControlNumber`, allowing you to correlate these responses to specific service lines from the original claim.
* If you don’t set the line item control number for a service line, Stedi uses a ULID.
### Character restrictions
Only use the X12 Basic and Extended character sets in request data. Using characters outside these sets may cause validation and HTTP `400` errors.
The X12 Basic character set includes uppercase letters, digits, space, and some special characters. Lowercase letters and special language characters like `ñ` are not included.
The following special characters are included:

The Extended character set includes the characters listed in Basic, plus lowercase letters and additional special characters, such as `@`.
The following additional special characters are included:

Don't include the following characters in your request data: `~`, `*`, `:` and `^`. They are reserved for delimiters in the resulting X12 EDI transaction, and X12 doesn't support using escape sequences to represent delimiters or special characters. Stedi returns a `400` error if you include these restricted characters in your request.
### Sample request and response
The following example sends an institutional claim. The response shape contains summary information from Stedi about the claim submission and whether it was successful.
{/* schema:InstitutionalClaimsSubmissionRequestContent */}
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/institutionalclaims/v1/submission \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"usageIndicator": "T",
"tradingPartnerName": "UnitedHealthcare",
"tradingPartnerServiceId": "87726",
"submitter": {
"organizationName": "Test Facility",
"contactInformation": {
"name": "Test Facility",
"phoneNumber": "2225551234"
},
"taxId": "123456789"
},
"receiver": {
"organizationName": "UnitedHealthcare"
},
"subscriber": {
"memberId": "98765",
"paymentResponsibilityLevelCode": "P",
"firstName": "JANE",
"lastName": "DOE",
"groupNumber": "67890"
},
"claimInformation": {
"claimFilingCode": "ZZ",
"patientControlNumber": "",
"claimChargeAmount": "500.00",
"placeOfServiceCode": "11",
"claimFrequencyCode": "0",
"planParticipationCode": "C",
"benefitsAssignmentCertificationIndicator": "Y",
"releaseInformationCode": "Y",
"principalDiagnosis": {
"qualifierCode": "ABK",
"principalDiagnosisCode": "R45851"
},
"serviceLines": [
{
"assignedNumber": "0",
"serviceDate": "20241015",
"serviceDateEnd": "20241015",
"lineItemControlNumber": "111222333",
"institutionalService": {
"serviceLineRevenueCode": "90",
"lineItemChargeAmount": "500.00",
"measurementUnit": "UN",
"serviceUnitCount": "1",
"procedureIdentifier": "HC",
"procedureCode": "H0001"
}
}
],
"claimCodeInformation": {
"admissionTypeCode": "3",
"admissionSourceCode": "9",
"patientStatusCode": "30"
},
"claimDateInformation": {
"admissionDateAndHour": "202409091000",
"statementBeginDate": "20241015",
"statementEndDate": "20241015"
}
},
"providers": [
{
"providerType": "BillingProvider",
"npi": "1999999976",
"employerId": "123456789",
"organizationName": "Test Facility",
"address": {
"address1": "123 Mulberry Street",
"city": "Seattle",
"state": "WA",
"postalCode": "111135272"
},
"contactInformation": {
"name": "Test Facility",
"phoneNumber": "2065551234"
}
},
{
"providerType": "AttendingProvider",
"npi": "1999999976",
"firstName": "Doctor",
"lastName": "Provider",
"contactInformation": {
"name": "name"
}
}
]
}'
```
{/* schema:InstitutionalClaimsSubmissionResponseContent */}
```json
{
"status": "SUCCESS",
"controlNumber": "123456",
"tradingPartnerServiceId": "87726",
"claimReference": {
"correlationId": "01JABEX6DPF4FCT2J0Y0SGFCY8",
"patientControlNumber": "00001111222233334444",
"timeOfResponse": "2024-10-16T20:04:32.962Z",
"formatVersion": "5010",
"claimType": "INST",
"rhClaimNumber": "01JABEX6DPF4FCT2J0Y0SGFCY8"
},
"httpStatusCode": "200 OK",
"payer": {
"payerName": "UnitedHealthcare",
"payerID": "87726"
},
"meta": {
"traceId": "a742ab42-a6f3-4232-a88c-197d341afdbe"
}
}
```
### Test claims
All claims you submit through the API are sent to the payer as production claims unless you explicitly designate them as test data.
To send test claims:
* **JSON endpoint:** Set the `usageIndicator` property in the test claim body to `T`.
* **X12 EDI endpoint:** Set `ISA15` (Interchange Usage Indicator) to `T` (Test Data) instead of `P` (Production Data).
When you send a test claim, Stedi does not send it to the payer. Instead, it processes the claim as if it were sent to the payer and returns a response indicating whether the claim was successfully processed.
Designating a claim as test data allows you to filter for test claims on the [Transactions](https://portal.stedi.com/app/core/transactions) page in the Stedi portal.
Note that you will receive a 277CA claim acknowledgment in response to test claims, allowing you to test your workflow end to end, but you will not receive a test 835 ERA response.
### Concurrency limit
Institutional claim submission endpoints share a concurrency pool with other claim endpoints. For more information, visit [Concurrency limits](/api-reference#concurrency-limits).
### Recommended API clients
You may want to use an API client to make testing and debugging easier.
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.
Visit [API clients](/api-reference#api-clients) for a list of recommended clients you can use instead.
## View submitted claims
You can view the files that Stedi sends and receives in the [Transactions](https://portal.stedi.com/app/core/transactions) page of the Stedi portal.
On the [Transactions](https://portal.stedi.com/app/core/transactions) page, you can review and filter claims by **Usage** - production or test. Click any claim submission to review its details, including the full request and response payload.
## Cancel or resubmit claims
You may need to resubmit claims for several reasons, including changes to the patient's coverage, errors in the original claim's information, or appealing a denied claim. You may also need to cancel duplicate claims or claims that were submitted in error.
You can cancel and revise claims by resubmitting them through the Stedi portal, the API, or SFTP.
### Manual resubmission
To manually resubmit a claim through the Stedi portal:
1. Go to the [Transactions](https://portal.stedi.com/app/healthcare/transactions) page in your Stedi account and click the claim you want to resubmit.
2. Click **Edit and resubmit**. Stedi opens the claim in an interactive inspector, with the X12 EDI on the left and the EDI specification on the right.
3. Make any necessary changes to the claim EDI, then click **Review and submit**. Stedi shows a comparison of the original claim and the new claim containing your changes.
4. Click **Resubmit claim** to send the updated claim to the payer.
### Claim Frequency Code
Set the Claim Frequency Code to one of the following values. This is the `claimInformation.claimFrequencyCode` property in JSON and the `Loop 2300 CLM05-03` (Claim Frequency Code) component in X12 EDI.
* **Resubmit to Stedi or another payer:** Set to `1` - Admit thru Discharge Claim. Either Stedi rejected the claim due to validation errors, or you're resubmitting the claim to a different payer for the first time. In either case, the payer hasn't yet processed the claim.
* **Correct or replace claims:** Set to `7` - Replacement of Prior Claim. In this case, the payer processed the original claim.
* **Cancel claims:** Set to `8` - Void/Cancel of Prior Claim.
### Payer Claim Control Number
When correcting, replacing, or canceling claims, you should include the Payer Claim Control Number (sometimes called the ICN) from the original claim for identification. In JSON, this is the `claimInformation.claimSupplementalInformation.claimControlNumber` property. In X12 EDI, this is `Loop 2300 REF02`, where `REF01` = `F8` (Original Reference Number).
* The Payer Claim Control Number is different from the `claimInformation.patientControlNumber` (`Loop 2300 CLM01`) you sent in the original claim. It's also different from the Stedi-generated `controlNumber` returned in the API response.
* You can retrieve the Payer Claim Control Number from one of the payer's 277CA claim acknowledgments in the `transactions.payers.claimStatusTransactions.claimStatusDetails.patientClaimStatusDetails.claims.claimStatus.tradingPartnerClaimNumber` property.
### Patient Control Number
When correcting or replacing claims, we also recommend setting a new, unique Patient Control Number. This is the `claimInformation.patientControlNumber` property in JSON and `Loop 2300 CLM01` in X12 EDI. The payer includes this value in their 835 ERA, allowing you to easily correlate that response with your resubmission.
## Submit claims to a secondary or tertiary payer
In [coordination of benefits (COB)](/healthcare/coordination-of-benefits) scenarios, you'll need to submit a claim to multiple payers.
You must set the `subscriber.paymentResponsibilityLevelCode` to either `S` (when submitting to the secondary payer) or `T` (when submitting to the tertiary payer).
You must also include the following information about how prior payers have adjudicated the claim. For example, if a patient's private insurance plan (primary payer) adjusted the requested reimbursement amount and paid for its portion of the services, you must include that information in the claim you submit to Medicare (secondary payer). You can find these details in 835 ERA responses from prior payers.
### Claim information
You must submit one `claimInformation.otherSubscriberInformation` object for each prior payer. Supply all the required properties in the object plus the following additional information:
* `claimLevelAdjustments`: Provide if the prior payer made adjustments at the claim level. Codes and their associated amounts must come from ERAs sent by the prior payers. You can find these codes in the ERA's [`transactions.detailInfo.paymentInfo.claimAdjustments`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.claimAdjustments) object.
* `medicareInpatientAdjudication` (institutional claims only): You must include this if Medicare was one of the prior payers and reported inpatient adjudication information on the ERA.
* `medicareOutpatientAdjudication`: You must include this if Medicare was one of the prior payers and reported outpatient adjudication information on the ERA.
* `otherPayerName.otherPayerAdjudicationOrPaymentDate`: The date the payer adjudicated or paid the claim. You must provide this if you aren't providing a value in the `claimInformation.serviceLines.lineAdjudicationInformation.adjudicationOrPaymentDate` property.
* `payerPaidAmount`: This is the total amount in dollars the payer paid on this claim.
### Service line information
You must submit `serviceLines.lineAdjudicationInformation` objects when the prior payers provided line-level adjudication information. Submit one object for each prior payer. For each object, you should include the following properties.
* `adjudicationOrPaymentDate`: The date the payer adjudicated or paid the claim. Don't include this if you're providing a date in the `otherPayerName.otherPayerAdjudicationOrPaymentDate` property.
* `claimAdjustmentInformation`: You can find this information in the ERA's [`transactions.detailInfo.paymentInfo.serviceLines.serviceAdjustments`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.serviceLines.serviceAdjustments) object.
* `otherPayerPrimaryIdentifier`: The identifier for the other payer. This value should match the identifier you supplied for the payer in the `claimInformation.otherSubscriberInformation.otherPayerName.otherPayerIdentifier` property.
* `procedureCode`: The adjudicated procedure code for the service line.
* `serviceIdQualifier`: A code identify the type of procedure code. Visit [Claims code lists](/healthcare/claims-code-lists#composite-medical-procedure---product-or-service-id-qualifier-codes) for a complete list.
* `serviceLinePaidAmount`: The total amount in dollars the prior payer paid on this service line.
* `paidServiceUnitCount`: The number of paid units for the service line. When paid units are not present on the remittance advice, use the original billed units.
* `remainingPatientLiability`: The amount of the service line the patient is responsible for paying.
## Claim Filing Indicator Code
The Claim Filing Indicator Code indicates how a claim was filed with a payer, such as `MC` (Medicaid) or `CI` (Commercial Insurance Co.).
Choosing the correct claim filing indicator code is important for successful claim submission. Visit the [Claims code lists](/healthcare/claims-code-lists#choosing-the-right-code) documentation for best practices for selecting the appropriate code.
# Submit professional claims
Source: https://www.stedi.com/docs/healthcare/submit-professional-claims
***
title: Submit professional claims
sidebarTitle: "Professional claims"
-----------------------------------
You can send 837P professional claims to payers through the Stedi portal, the Professional Claims API, or an SFTP connection.
Once you send a claim, Stedi automatically receives and processes 277CA claim acknowledgment and 835 Electronic Remittance Advice (ERA) responses.
## Before sending claims
You may need to complete the following steps before sending claims.
### Transaction enrollment
All payers require providers to complete an enrollment process before they can start receiving 835 ERAs. Some payers also require enrollment before allowing providers to submit claims.
The [Stedi Payer Network](https://www.stedi.com/healthcare/network) lists which payers require transaction enrollment. Visit [Transaction enrollment](/healthcare/transaction-enrollment) for details about the transaction enrollment process.
### Coordination of benefits check
We recommend running a coordination of benefits (COB) check to ensure you submit claims to the correct payer. COB checks can help you determine:
* If a patient is covered by more than one health plan
* Whether coverage overlap requires coordination of benefits
* Each payer’s responsibility for payment (primacy) in coordination of benefits scenarios
Visit [Coordination of benefits (COB) checks](/healthcare/coordination-of-benefits) for more information.
## Manual submission
Manual claim submission can be useful for testing, QA, and debugging your pipeline. You can submit 837P professional claims manually through the [Create manual claim page](https://portal.stedi.com/app/healthcare/claims/create) in the Stedi portal.
The in-app form is based on the [NUCC 1500 claim form](https://nucc.org/index.php/1500-claim-form-mainmenu-35) but doesn’t support every data element. Specifically, it omits some parts of Item 19 (Additional Claim Information) and all of Item 24 supplemental information (shaded area). If you need this data, use the [API endpoints](#api-submission) instead.
To help prevent rejections, Stedi validates provider NPIs, diagnosis codes, and other key information. You can also see an auto-generated preview of the corresponding JSON payload for the [Professional Claims API](/api-reference/healthcare/post-healthcare-claims) to understand how the form maps to the request structure.
## SFTP submission
You can use Stedi’s fully-managed SFTP server to submit claims to to payers and retrieve claim responses without calling Stedi’s APIs.
You must submit claims in X12 EDI format, and Stedi returns claim responses through the SFTP connection in X12 EDI format. This makes Stedi SFTP a good option if you have an existing system that generates X12 EDI files and you want to send them through the Stedi clearinghouse without completing an API integration. Visit [SFTP connection](/healthcare/submit-claims-sftp-connection) for more information.
## API submission
Call one of the following endpoints to submit 837P professional claims:
* [Professional Claims](/api-reference/healthcare/post-healthcare-claims) to send requests in JSON
* [Professional Claims Raw X12](/api-reference/healthcare/post-healthcare-claims-raw-x12) to send requests in X12 EDI
Both endpoints return a synchronous response from Stedi in JSON format. Later, the payer will respond with a 277CA claim acknowledgment.
### Headers
When constructing the request, you must include the following information in HTTP headers:
* **`Authorization`:** [Generate an API key](https://portal.stedi.com/app/settings/api-keys) to use for authentication.
* **`Content-Type`:** Set to `application/json`.
### Body - JSON
The information you submit for a claim depends on your use case. Refer to the [Professional Claims](/api-reference/healthcare/post-healthcare-claims) endpoint for a complete list of properties. However, all claims require the following high-level information:
\| Information | Description |
\| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
\| `tradingPartnerServiceId` | This is the payer ID. Visit the [Payer Network](https://www.stedi.com/healthcare/network) for a complete list. |
\| `tradingPartnerName` | This is the payer's business name, like Cigna or Aetna. |
\| `submitter` object | Information about the entity submitting the claim. This can be either an individual or an organization, such as a doctor, hospital, or insurance company. |
\| `receiver` object | Information about the payer, such as an insurance company or government agency. |
\| `subscriber` and/or `dependent` objects | Information about the patient who received the medical services. Note that if a dependent has their own, unique member ID for their health plan, you should submit their information in the `subscriber` object and omit the `dependent` object from the request. You can check whether the dependent has a unique member ID by submitting an [Eligibility Check](/api-reference/healthcare/post-healthcare-eligibility) to the payer for the dependent. The payer will return the member ID in the `dependents.memberId` field, if present. |
\| `claimInformation` object | Information about the claim, such as the patient control number, claim charge amount, and place of service code. It also includes information about each individual service line included in the claim. |
\| `billing` object | Information about the billing provider, such as the [NPI](/healthcare/national-provider-identifier), taxonomy code, and organization name. |
#### Service line identification
A claim can contain multiple service lines. Since the payer may accept, reject, or pay a subset of those lines, you can receive an 835 ERA that references a `patientControlNumber`, but only pertains to some of the service lines.
However, the `claimInformation.serviceLines.providerControlNumber` serves as a unique identifier for each service line in your claim submission. This value appears in the 277CA claim acknowledgment and 835 ERA as the `lineItemControlNumber`, allowing you to correlate these responses to specific service lines from the original claim. If you don't set the `providerControlNumber` for a service line, Stedi uses a random UUID.
Stedi returns service line identifiers in the `claimReference.serviceLines` object of the synchronous API response.
#### Conditional requirements
Note that objects marked as **required** are required for all requests, while others are conditionally required depending on the circumstances. When you include a conditionally required object, you must include all of its required properties.
For example, you must always include the `subscriber` object in your request, but you only need to include the `supervising` object when the rendering provider is supervised by a physician.
### Body - X12 EDI
You must send a payload in [837 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-professional-x222a1/01HR60MDFAGCSEJNKY8J38867Y).
Note the following requirements and behavior when sending professional claims through the raw X12 endpoint.
#### Envelope and header
Stedi generates its own `ISA` and `GS` headers and `IEA` and `GE` trailers before sending your claim to the payer. You can submit your claim to Stedi with any values in these segments, as long as they conform to the X12 EDI specification.
However, you must set `ST03` (Implementation Guide Version Name) to `005010X222A1`.
#### Payer ID
You must submit a payer identifier in `Loop 2010BB` (Payer Name) `NM109` so Stedi can route your claim to the correct payer. This identifier **must** be a payer ID or payer ID alias listed in the [Payer Network](https://www.stedi.com/healthcare/network?page=0). For example, you could use `60054`, `HPQRS`, `AETNA`, or any other listed payer ID alias for Aetna.
#### `CLM01` (Patient Control Number)
We **strongly recommend** submitting a unique value for `Loop 2300` (Claim Information) `CLM01` (Patient Control Number). The payer returns this value in related transactions, such as the 277CA and 835 ERA, so you can correlate responses and real-time claim status checks with the original claim.
We recommend using only alphanumeric characters and generating unique values that are the shortest possible length. Stedi accepts any valid value, but some payers replace non-alphanumeric characters and truncate shorter than the official 20-character limit. When this happens, the payer returns a different identifier in responses than the one you originally sent, making it more difficult to correlate the claim and perform real-time claim status checks.
#### Service line identification
A claim can contain multiple service lines. Since the payer may accept, reject, or pay a subset of those lines, you can receive an 835 response that references a patient control number, but only pertains to some of the service lines.
However, the line item control number serves as a unique identifier for each service line in your claim submission.
* You can set the line item control number in `Loop 2400 REF02`, when `REF01` = `6R`. The line item control number appears in the 277CA and 835 ERA responses as the `lineItemControlNumber`, allowing you to correlate these responses to specific service lines from the original claim.
* If you don’t set the line item control number for a service line, Stedi uses a ULID.
### Character restrictions
Only use the X12 Basic and Extended character sets in request data. Using characters outside these sets may cause validation and HTTP `400` errors.
The X12 Basic character set includes uppercase letters, digits, space, and some special characters. Lowercase letters and special language characters like `ñ` are not included.
The following special characters are included:

The Extended character set includes the characters listed in Basic, plus lowercase letters and additional special characters, such as `@`.
The following additional special characters are included:

In addition, the following characters are reserved for delimiters in the final X12 EDI transaction to the payer: `~`, `*`, `:`, and `^`. X12 doesn’t support using escape sequences to represent delimiters or special characters. Stedi returns a `400` error if you use these restricted characters improperly.
* **JSON endpoint:** Don’t include delimiter characters anywhere in your request data.
* **Raw X12 endpoint:** You can use these characters as delimiters, but not in the body of the request data.
### Sample request and response
The following examples send a professional claim. The response shape is the same for both the JSON and X12 EDI endpoints. It contains summary information from Stedi about the claim submission and whether it was successful.
{/* schema:ClaimsSubmissionRequestContent */}
{/* replace::1234567890 */}
{/* replace::1234567890 */}
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/professionalclaims/v3/submission \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"usageIndicator": "T",
"tradingPartnerServiceId": "6400",
"submitter": {
"organizationName": "Test Data Health Services, Inc.",
"submitterIdentification": "",
"contactInformation": {
"name": "Test Data Health Services, Inc.",
"phoneNumber": "5552223333"
}
},
"receiver": {
"organizationName": "Cigna"
},
"subscriber": {
"memberId": "U7777788888",
"paymentResponsibilityLevelCode": "P",
"subscriberGroupName": "Cigna",
"firstName": "John",
"lastName": "Anon",
"gender": "M",
"dateOfBirth": "20000101",
"groupNumber": "3335555",
"address": {
"address1": "2222 Random St",
"city": "A City",
"state": "NY",
"postalCode": "123450000"
}
},
"billing": {
"providerType": "BillingProvider",
"npi": "",
"employerId": "123456789",
"taxonomyCode": "2084P0800X",
"organizationName": "Therapy Associates",
"address": {
"address1": "123 Some St",
"address2": "Floor 1",
"city": "A City",
"state": "NY",
"postalCode": "123450000"
},
"contactInformation": {
"name": "Test Data Health Services, Inc.",
"phoneNumber": "5553334444"
}
},
"claimInformation": {
"claimFilingCode": "CI",
"patientControlNumber": "",
"claimChargeAmount": "109.20",
"placeOfServiceCode": "02",
"claimFrequencyCode": "1",
"signatureIndicator": "Y",
"planParticipationCode": "A",
"benefitsAssignmentCertificationIndicator": "Y",
"releaseInformationCode": "Y",
"healthCareCodeInformation": [
{
"diagnosisTypeCode": "ABK",
"diagnosisCode": "F1111"
}
],
"serviceFacilityLocation": {
"organizationName": "Smith Associates",
"address": {
"address1": "1234 Other St",
"city": "A City",
"state": "NY",
"postalCode": "123450000"
},
"npi": "1999999984"
},
"serviceLines": [
{
"serviceDate": "20240101",
"professionalService": {
"procedureIdentifier": "HC",
"procedureCode": "90837",
"procedureModifiers": [
"95"
],
"lineItemChargeAmount": "109.20",
"measurementUnit": "UN",
"serviceUnitCount": "1",
"compositeDiagnosisCodePointers": {
"diagnosisCodePointers": [
"1"
]
}
},
"providerControlNumber": "111222333",
"renderingProvider": {
"providerType": "RenderingProvider",
"npi": "",
"taxonomyCode": "111YP2000X",
"firstName": "Jane",
"lastName": "Smith"
}
}
]
},
"tradingPartnerName": "Cigna"
}'
```
```bash
curl --request POST \
--url https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/professionalclaims/v3/raw-x12-submission \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"x12": "ISA*00* *00* *ZZ*001690149382 *ZZ*STEDITEST *240630*0847*^*00501*000000001*0*T*>~GS*HC*001690149382*STEDITEST*20240630*084744*000000001*X*005010X222A1~ST*837*0001*005010X222A1~BHT*0019*00*01J1M588QT2TAV2N093GNJ998T*20240630*0847*CH~NM1*41*2*Test Data Health Services, Inc.*****46*123567890~PER*IC*Test Data Health Services, Inc.*TE*5552223333~NM1*40*2*Cigna*****46*60054~HL*1**20*1~PRV*BI*PXC*2084P0800X~NM1*85*2*Therapy Associates*****XX*1999999984~N3*123 Some St*Floor 1~N4*A City*NY*123450000~REF*EI*832675429~PER*IC*Test Data Health Services, Inc.*TE*5553334444~HL*2*1*22*0~SBR*P*18*3335555******CI~NM1*IL*1*Anon*John****MI*U7777788888~N3*2222 Random St~N4*A City*NY*123450000~DMG*D8*20000101*M~NM1*PR*2*Cigna*****PI*60054~CLM*22266555*109.0***02>B>1*Y*A*Y*Y~HI*ABK>F1111~NM1*82*1*Smith*Jane****XX*1999999984~PRV*PE*PXC*111YP2000X~NM1*77*2*Smith Associates*****XX*1999999984~N3*1234 Other St~N4*A City*NY*123450000~LX*1~SV1*HC>90837>95*109.2*UN*1.0***1~DTP*472*D8*20240101~SE*30*0001~GE*1*000000001~IEA*1*000000001~"
}'
```
{/* schema:ClaimsSubmissionResponseContent */}
```json
{
"status": "SUCCESS",
"controlNumber": "555123",
"tradingPartnerServiceId": "6400",
"claimReference": {
"correlationId": "01HTQX03MMP4XHBT4QBGDAD9DG",
"patientControlNumber": "22266555",
"timeOfResponse": "2024-04-05T19:50:34.275Z",
"payerID": "6400",
"formatVersion": "5010",
"rhclaimNumber": "01HTQX03MMP4XHBT4QBGDAD9DG"
},
"httpStatusCode": "200 OK",
"meta": {
"traceId": "bef31123-34d8-46b6-b1ff-2a534d0e9a06"
},
"payer": {
"payerName": "Cigna",
"payerID": "6400"
}
}
```
### Test claims
All claims you submit through the API are sent to the payer as production claims unless you explicitly designate them as test data.
To send test claims:
* **JSON endpoint:** Set the `usageIndicator` property in the test claim body to `T`.
* **X12 EDI endpoint:** Set `ISA15` (Interchange Usage Indicator) to `T` (Test Data) instead of `P` (Production Data).
When you send a test claim, Stedi does not send it to the payer. Instead, it processes the claim as if it were sent to the payer and returns a response indicating whether the claim was successfully processed.
Designating a claim as test data allows you to filter for test claims on the [Transactions](https://portal.stedi.com/app/core/transactions) page in the Stedi portal.
Note that you will receive a 277CA claim acknowledgment in response to test claims, allowing you to test your workflow end to end, but you will not receive a test 835 ERA response.
### Concurrency limit
Professional claim submission endpoints share a concurrency pool with other claim endpoints. For more information, visit [Concurrency limits](/api-reference#concurrency-limits).
### Recommended API clients
You may want to use an API client to make testing and debugging easier.
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.
Visit [API clients](/api-reference#api-clients) for a list of recommended clients you can use instead.
## View submitted claims
You can view the files that Stedi sends and receives on the [Files](https://portal.stedi.com/app/core/file-executions) page of the Stedi portal.
On the [Transactions](https://portal.stedi.com/app/core/transactions) page, you can review and filter claims by **Usage** - production or test. Click any claim submission to review its details, including the full request and response payload, processing events, and a link to download the auto-generated 1500 Claim Form PDF.
## Cancel or resubmit claims
You may need to resubmit claims for several reasons, including changes to the patient's coverage, errors in the original claim's information, or appealing a denied claim. You may also need to cancel duplicate claims or claims that were submitted in error.
You can cancel and revise claims by resubmitting them through the Stedi portal, the API, or SFTP.
### Manual resubmission
To manually resubmit a claim through the Stedi portal:
1. Go to the [Transactions](https://portal.stedi.com/app/healthcare/transactions) page in your Stedi account and click the claim you want to resubmit.
2. Click **Edit and resubmit**. Stedi opens the claim in an interactive editor, with the X12 EDI on the left and the EDI specification on the right.
3. Make any necessary changes to the claim EDI, then click **Review and submit**. Stedi shows a comparison of the original claim and the new claim containing your changes.
4. Click **Resubmit claim** to send the updated claim to the payer.
### Claim Frequency Code
Set the Claim Frequency Code to one of the following values. This is the `claimInformation.claimFrequencyCode` property in JSON and the `Loop 2300 CLM05-03` (Claim Frequency Code) component in X12 EDI.
* **Resubmit to Stedi or another payer:** Set to `1` - Admit thru Discharge Claim. Either Stedi rejected the claim due to validation errors, or you're resubmitting the claim to a different payer for the first time. In either case, the payer hasn't yet processed the claim.
* **Correct or replace claims:** Set to `7` - Replacement of Prior Claim. In this case, the payer processed the original claim.
* **Cancel claims:** Set to `8` - Void/Cancel of Prior Claim.
### Payer Claim Control Number
When correcting, replacing, or canceling claims, you should include the Payer Claim Control Number (sometimes called the ICN) from the original claim for identification. In JSON, this is the `claimInformation.claimSupplementalInformation.claimControlNumber` property. In X12 EDI, this is `Loop 2300 REF02`, where `REF01` = `F8` (Original Reference Number).
* The Payer Claim Control Number is different from the `claimInformation.patientControlNumber` (`Loop 2300 CLM01`) you sent in the original claim. It's also different from the Stedi-generated `controlNumber` returned in the API response.
* You can retrieve the Payer Claim Control Number from one of the payer's 277CA claim acknowledgments in the `transactions.payers.claimStatusTransactions.claimStatusDetails.patientClaimStatusDetails.claims.claimStatus.tradingPartnerClaimNumber` property.
### Patient Control Number
When correcting or replacing claims, we also recommend setting a new, unique Patient Control Number. This is the `claimInformation.patientControlNumber` property in JSON and `Loop 2300 CLM01` in X12 EDI. The payer includes this value in their 835 ERA, allowing you to easily correlate that response with your resubmission.
## 275 claim attachments
If the claim requires attachments, you must include additional details about the attachments in the appropriate objects:
* Attachments for entire claim: [`claimInformation.claimSupplementalInformation.reportInformation`](/api-reference/healthcare/post-healthcare-claims#body.claimInformation.claimSupplementalInformation.reportInformation) or [`claimInformation.claimSupplementalInformation.reportInformations`](/api-reference/healthcare/post-healthcare-claims#body.claimInformation.claimSupplementalInformation.reportInformations) (multiple attachments)
* Attachments for a specific service line: [`claimInformation.serviceLines.serviceLineSupplementalInformation`](/api-reference/healthcare/post-healthcare-claims#body.claimInformation.serviceLines.serviceLineSupplementalInformation)
Visit [Claim attachments](/healthcare/submit-claim-attachments) for complete instructions.
## Submit to a secondary or tertiary payer
In [coordination of benefits (COB)](/healthcare/coordination-of-benefits) scenarios, you'll need to submit a claim to multiple payers.
You must set the `subscriber.paymentResponsibilityLevelCode` to either `S` (when submitting to the secondary payer) or `T` (when submitting to the tertiary payer).
You must also include the following information about how prior payers have adjudicated the claim. For example, if a patient's private insurance plan (primary payer) adjusted the requested reimbursement amount and paid for its portion of the services, you must include that information in the claim you submit to Medicare (secondary payer). You can find these details in 835 ERA responses from prior payers.
### Claim information
You must submit one `claimInformation.otherSubscriberInformation` object for each prior payer. Supply all the required properties in the object plus the following additional information:
* `claimLevelAdjustments`: Provide if the prior payer made adjustments at the claim level. Codes and their associated amounts must come from ERAs sent by the prior payers. You can find these codes in the ERA's [`transactions.detailInfo.paymentInfo.claimAdjustments`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.claimAdjustments) object.
* `medicareInpatientAdjudication` (institutional claims only): You must include this if Medicare was one of the prior payers and reported inpatient adjudication information on the ERA.
* `medicareOutpatientAdjudication`: You must include this if Medicare was one of the prior payers and reported outpatient adjudication information on the ERA.
* `otherPayerName.otherPayerAdjudicationOrPaymentDate`: The date the payer adjudicated or paid the claim. You must provide this if you aren't providing a value in the `claimInformation.serviceLines.lineAdjudicationInformation.adjudicationOrPaymentDate` property.
* `payerPaidAmount`: This is the total amount in dollars the payer paid on this claim.
### Service line information
You must submit `serviceLines.lineAdjudicationInformation` objects when the prior payers provided line-level adjudication information. Submit one object for each prior payer. For each object, you should include the following properties.
* `adjudicationOrPaymentDate`: The date the payer adjudicated or paid the claim. Don't include this if you're providing a date in the `otherPayerName.otherPayerAdjudicationOrPaymentDate` property.
* `claimAdjustmentInformation`: You can find this information in the ERA's [`transactions.detailInfo.paymentInfo.serviceLines.serviceAdjustments`](/api-reference/healthcare/get-healthcare-reports-835#response.transactions.detailInfo.paymentInfo.serviceLines.serviceAdjustments) object.
* `otherPayerPrimaryIdentifier`: The identifier for the other payer. This value should match the identifier you supplied for the payer in the `claimInformation.otherSubscriberInformation.otherPayerName.otherPayerIdentifier` property.
* `procedureCode`: The adjudicated procedure code for the service line.
* `serviceIdQualifier`: A code identify the type of procedure code. Visit [Claims code lists](/healthcare/claims-code-lists#composite-medical-procedure---product-or-service-id-qualifier-codes) for a complete list.
* `serviceLinePaidAmount`: The total amount in dollars the prior payer paid on this service line.
* `paidServiceUnitCount`: The number of paid units for the service line. When paid units are not present on the remittance advice, use the original billed units.
* `remainingPatientLiability`: The amount of the service line the patient is responsible for paying.
## Claim Filing Indicator Code
The Claim Filing Indicator Code indicates how a claim was filed with a payer, such as `MC` (Medicaid) or `CI` (Commercial Insurance Co.).
Choosing the correct claim filing indicator code is important for successful claim submission. Visit the [Claims code lists](/healthcare/claims-code-lists#choosing-the-right-code) documentation for best practices for selecting the appropriate code.
## Set a claim's correlation ID
A claim's correlation ID is a business identifier that you can use to track and manage claims.
* When you submit claims through the JSON endpoint, Stedi generates the correlation ID for you, and this value will be unique for each claim.
* When you submit claims in X12 EDI through the API or an [SFTP connection](/healthcare/submit-claims-sftp-connection), you can specify your own correlation ID in the `BHT03` element. This allows you to use the same value for multiple claims if desired.
## CMS-1500 claim form PDF
Stedi automatically generates a PDF [CMS-1500 claim form](https://www.nucc.org/index.php/1500-claim-form-mainmenu-35) for each professional claim you submit. You can manually download the form on the transaction details page for the claim in the Stedi portal or retrieve them programmatically through the following endpoints:
* [CMS-1500 PDF: Business Identifier](/api-reference/healthcare/get-pdf-1500-business-identifier): Retrieve PDFs through a claim's business identifier. You can find the business identifier value in the `claimReference.correlationId` property Stedi returns in the synchronous claim submission response.
* [CMS-1500 PDF: Transaction ID
](/api-reference/healthcare/get-pdf-1500): Retrieve PDFs through the `transactionId` Stedi assigns to the processed claim. This ID is included in the transaction processed event for the claim, which you can receive automatically through [webhooks](/healthcare/configure-webhooks). You can also retrieve this ID from the transaction's details page in Stedi.
Payers have strict requirements for submitted CMS-1500 claim forms. If you plan to send generated PDFs to payers or retain them for your records, we strongly recommend visiting [CMS-1500 Claim Form PDF](/healthcare/cms-1500-claim-form-pdf) for information about how to structure claim submissions for optimal generation, the correct printer settings for generated PDFs, and general best practices.
# Supported payers
Source: https://www.stedi.com/docs/healthcare/supported-payers
***
## title: Supported payers
Visit the [Payer Network](https://www.stedi.com/healthcare/network) to review a complete list of supported payers for eligibility and claims processing. In the network, you can:
* Search for payers using their name, payer ID, or payer ID aliases.
* Find the payer IDs you need to send transactions through Stedi APIs.
* Determine which payers require [transaction enrollment](/healthcare/transaction-enrollment) before you can begin exchanging transactions.
## Medical vs. dental payers
You can determine which payers support medical use cases, dental use cases, or both.
* The [Payer Network](https://www.stedi.com/healthcare/network) lists **Coverage types** for each payer that indicate supported use cases.
* The [Retrieve Payer](/api-reference/healthcare/get-payer), [List Payers](/api-reference/healthcare/get-payers), and [Search Payers](/api-reference/healthcare/get-search-payers) endpoints return a `coverageTypes` array for each payer indicating supported use cases.
For example, Aetna's **Coverage types** in the network are **Dental, Medical**. That means you can submit eligibility checks and claims for both medical and dental services to Aetna.
## Payers API
You can use the following endpoints to search for payers and retrieve their details.
* [Retrieve payer](/api-reference/healthcare/get-payer): Retrieve a specific payer record using the [Stedi payer ID](/healthcare/supported-payers#stedi-payer-id), a unique identifier Stedi assigns to each payer that will never change
* [List Payers JSON](/api-reference/healthcare/get-payers): List all supported payers in JSON format
* [List Payers CSV](/api-reference/healthcare/get-payers-csv): List all supported payers in CSV format
* [Search Payers](/api-reference/healthcare/get-search-payers): Search for payers by name, payer ID, or payer ID alias - fuzzy matching is supported. Results are returned in JSON format.
These endpoints are especially useful when you want to embed payer details or search capabilities into your system or application. For example, you could use the Search Payers endpoint to allow patients to search for and select their insurance provider in a patient intake form.
## Other names
The Payer Network includes other names for many payers. These additional names help you search for and identify payers using the name most familiar to your organization. For example, “Eaton Benefits Ohio” is an alternative associated with “Cigna”—searching for either name returns the same payer within the database.
## Payer IDs
The Payer Network includes three types of payer IDs. You can use any of these IDs to send transactions through Stedi.
### Primary payer ID
The primary payer ID is the most commonly used ID for a payer and most often corresponds to the name the payer uses internally and provides to patients on member ID cards.
### Stedi payer ID
The Stedi payer ID is a unique identifier Stedi assigns to each payer. This ID will not change, even if the primary payer ID is updated. We maintain a list of Stedi payer IDs to ensure that 1) you can always refer to a payer using a consistent identifier, 2) we can more easily route requests to the payer through the most reliable connection behind the scenes, and 3) we can update our products without introducing breaking changes.
You may want to use the Stedi payer ID for requests if you are building a system that requires a consistent and immutable set of payer IDs.
### Payer ID aliases
These are alternative IDs associated with a payer. If a payer changes their primary payer ID, payer ID aliases ensure that customers who still refer to the old ID can find the payer and continue sending transactions to the payer uninterrupted. Some payers also have different payer IDs for different plans. Payer ID aliases ensure that requests using these IDs are routed to the same payer.
## Stedi payer errors
Stedi returns the following error messages when a payer is not supported or enrolled properly.
\| Error message | Possible causes and resolutions |
\| ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
\| `Payer is not configured for {transaction type}. Please contact Stedi support to resolve.` | Stedi does not yet support this transaction type for this payer, or there is a mis-mapping of payer IDs. Contact us with the name of the payer, and we'll investigate the issue. |
\| `Payer connection does not support {transaction type}. Please contact Stedi support to discuss connectivity options.` | Stedi has a connection to this payer, but it doesn't currently support this functionality (real-time eligibility or claim submission). Contact us for a timeline on enabling it. |
\| `Payer is not configured. Please check our published payer list or contact Stedi support to resolve.` | Stedi doesn't recognize the payer ID you provided. Double-check the payer ID in the [Stedi Payer Network](https://www.stedi.com/healthcare/network), or contact us with the name of the payer, and we will help you determine the correct payer ID. |
\| `Payer is not supported. Please contact Stedi support to discuss connectivity options.` | Stedi doesn't yet have connectivity to this payer. We're likely already working on it - contact us for details about the connectivity timeline. |
# Test mode
Source: https://www.stedi.com/docs/healthcare/test-mode
***
title: Test mode
sidebarTitle: Test mode
-----------------------
Test mode provides a separate test environment where you can realistically simulate transactions in your Stedi account without PHI/PII and without sending any data to payers.
You can access test mode in your account at any time by toggling **Test mode** to **ON**.
Mock transactions you send in test mode are free for testing purposes and won’t incur any charges from Stedi.
## Send mock eligibility checks
You can submit mock real-time eligibility checks through the manual [eligibility check form](https://portal.stedi.com/app/healthcare/checks/create). You can choose from a variety of predefined requests for well-known payers, including:
* Aetna
* Cigna
* UnitedHealthcare
* National Centers for Medicare & Medicaid Services (CMS)
* Many more - Visit [Eligibility mock requests](/api-reference/healthcare/mock-requests-eligibility-checks) for a complete list
For each mock request, Stedi returns a realistic mock benefits response for that payer so you can get a sense for the kinds of data you'll receive in production. The benefits responses include examples of copays, deductibles, and other patient payment responsibilities, as well as active coverage.
You can also submit a mock [Medicare Beneficiary Identifier (MBI) lookup](/healthcare/mbi-lookup). MBI lookups allow you to use a patient's Social Security Number (SSN) to retrieve their MBI and complete benefits information from the Centers for Medicare and Medicaid Services (CMS).
### Test the Stedi Agent
The [Stedi Agent](/healthcare/eligibility-manager#stedi-agent) resolves recoverable eligibility check errors automatically with the same best practices our Support team uses for troubleshooting. You can run a specific mock eligibility check to evaluate the Stedi Agent:
1. Create a new eligibility check and select **Stedi Agent** as the payer. Keep all other properties set to their defaults.
2. Submit the check. It's designed to fail so you can watch the agent resolve issues in real time. Specifically, it returns `AAA` error `73` (Invalid/Missing Subscriber/Insured Name).
3. Click **Resolve with Stedi Agent**. The agent runs in **Debug view** to fix the error and eventually produce a successful mock eligibility response.
## Review eligibility check results
After you submit a mock eligibility check, you can review all of the request and response details in [Eligibility Manager](/healthcare/eligibility-manager). This includes:
* A list of historical eligibility checks that you can filter by status, payer ID, date, and error code.
* The raw API request and response.
* A user-friendly benefits view designed to help you quickly understand the patient's active coverage and payment responsibilities, such as co-pay and deductible amounts.
* Eligibility check **Debug** view, which allows you to to systematically troubleshoot failed checks until you receive a successful response from the payer.
## Explore the Stedi portal
The test environment allows you to get familiar with Stedi's UI tools and learn more about how you can use Stedi to automate claims and eligibility check workflows.
## Not supported
The following features aren't currently supported:
* [Raw X12 real-time eligibility checks](/api-reference/healthcare/post-healthcare-eligibility-raw-x12)
* [Batch eligibility checks](/healthcare/batch-refresh-eligibility-checks)
* [Transaction enrollment](/healthcare/transaction-enrollment)
* [Insurance discovery checks](/healthcare/insurance-discovery)
* [Coordination of benefits (COB) checks](/healthcare/coordination-of-benefits)
* Claims processing, including [837 claims submission](/healthcare/submit-professional-claims), [275 claim attachment](/healthcare/submit-claim-attachments), [277CA claim acknowledgments](/healthcare/receive-claim-responses#277ca-claim-acknowledgment), [835 ERAs](/healthcare/receive-claim-responses#835-electronic-remittance-advice-era), and [276/277 real-time claim status](/healthcare/check-claim-status)
* Custom mock data or payer selection
# Transaction enrollment
Source: https://www.stedi.com/docs/healthcare/transaction-enrollment
***
## title: Transaction enrollment
Transaction enrollment is the process of registering a provider to exchange specific healthcare transactions with a payer. It involves submitting information about the provider, including their name, tax ID, [NPI](/healthcare/national-provider-identifier), billing address, and contact information.
## Do I need to enroll my provider?
For 835 Electronic Remittance Advice (ERAs), always yes. For other transactions, it depends on the payer.
Check the [Payer Network](https://www.stedi.com/healthcare/network) or use the [Payers API](/api-reference/healthcare/get-payers) to determine whether your payers require enrollment for the transaction types you want to send and receive. Each transaction type is marked as either:
* Supported, enrollment not required
* Supported, enrollment required
* Not supported
For example, the following payer record shows that Blue Cross Blue Shield of North Carolina requires enrollments for 835 ERAs, as indicated in the `transactionSupport.claimPayment` property.
```json
{
"stediId": "UPICO",
"displayName": "Blue Cross Blue Shield of North Carolina",
"primaryPayerId": "BCSNC",
"transactionSupport": {
"eligibilityCheck": "SUPPORTED",
"claimStatus": "SUPPORTED",
"claimSubmission": "SUPPORTED",
"claimPayment": "ENROLLMENT_REQUIRED",
"dentalClaimSubmission": "SUPPORTED",
"professionalClaimSubmission": "SUPPORTED",
"institutionalClaimSubmission": "SUPPORTED",
"coordinationOfBenefits": "SUPPORTED",
"unsolicitedClaimAttachment": "NOT_SUPPORTED"
}
// truncated for brevity
}
```
If enrollment for a supported transaction type is:
* **Not required:** The provider can start exchanging transactions through Stedi right away. They'll include their information (like their [NPI](/healthcare/national-provider-identifier)) in transactions as needed.
* **Required:** The provider must complete transaction enrollment before they can start exchanging those transactions through Stedi. Note that ERA enrollment is exclusive to one clearinghouse. Switching a provider to Stedi stops ERA delivery through the previous clearinghouse.
## How long does enrollment take?
Most enrollments are completed within 24 - 48 hours. However, some payers may take up to 30 days, depending on their internal processes and requirements.
Check out [FAQ](#faq) for answers to other common questions about transaction enrollment.
## Enrollment process
Stedi handles the entire enrollment process for you, including submitting the required information to the payer and monitoring the status of the enrollment.
Here's how it works:
The provider record includes the information required to enroll the provider with payers, including the provider's name, tax ID, [NPI](/healthcare/national-provider-identifier), and contact information.
You can [create enrollment requests](#create-enrollment-requests) individually through the Stedi portal, in bulk through CSV import, or programmatically through the API. Stedi gets alerted about new enrollment requests once they're in `SUBMITTED` status.
For each provider, you'll create one enrollment request per transaction type. For example, you would create three separate requests to enroll a provider for 837P professional claims, 270 real-time eligibility checks, and 835 ERAs.
Stedi begins the enrollment process with the payer and sets the enrollment status to `PROVISIONING`. We'll reach out to you in your dedicated Slack or Teams channel with resources and to answer any follow-up questions.
Our network and enrollment operations team knows the nuances of each payer's enrollment requirements and maintains a public repository of payers that require additional steps through our [Transaction Enrollments Hub](https://enrollments.stedi.com/?v=1a7685bc14df80ed8e07000c941f6bff).
* You can make the process faster by authorizing Stedi to sign PDF enrollment forms on your behalf. Visit [Delegated signature authority (recommended)](#delegated-signature-authority-recommended) for details.
* If payers have additional requirements as part of their standard enrollment process, Stedi contacts you with clear, actionable steps to move the process forward.
Once the enrollment is approved, the enrollment status is set to `LIVE`, and the provider can start exchanging the enrolled transactions with the payer.
### Enrollment statuses
An enrollment request can have one of the following statuses:

* `DRAFT`: You are still editing the record and it has not been submitted to Stedi.
* `SUBMITTED`: You have successfully submitted the request and it is in Stedi's queue for review. Once you submit an enrollment request, you can no longer update it without contacting support. If an enrollment request is in this status for more than 2 days, we are likely waiting for additional information or action from the provider.
* `PROVISIONING`: Stedi has begun the process of completing the enrollment with the payer.
* `LIVE`: The enrollment process is complete, and the specified provider can begin exchanging the listed transaction types with the payer.
* `REJECTED`: The payer rejected the enrollment. Common reasons for rejection include incorrect details in the request and that the provider is not credentialed with the payer. Customer support will contact you with reasons for rejection and next steps.
* `CANCELED`: The enrollment has been terminated per customer or provider request. You can only [cancel enrollments](#cancel-enrollments) that are in `DRAFT` or `SUBMITTED` status.
### Delegated signature authority (recommended)
You can reduce manual work by 90% and complete enrollments significantly faster by authorizing Stedi to sign PDF enrollment forms on your behalf.
Here's how delegated signature authority works:
1. Complete a one-time delegated signature authority agreement that gives Stedi permission to sign enrollment forms for you.
* If you manage enrollments for providers, you'll also need to collect delegated signature authority from them during onboarding.
* Some providers may not allow delegated signing for various reasons, such as their internal policies or legal requirements. In these cases, you can still submit enrollment requests, but the provider must sign the forms directly.
2. Submit [enrollment requests](#create-enrollment-requests).
3. When a payer requires a signature, Stedi checks whether delegated signing is allowed.
* If allowed, Stedi signs and submits the form automatically.
* If not allowed, the provider must sign the form directly. Stedi notifies you on the enrollment request and provides instructions to complete the process.
All documents Stedi signs on your behalf are available on the enrollment request's [details page](#manage-enrollment-documents), where you can download them at any time.
Delegated signature authority is available on all paid Stedi plans. To enable it, contact Stedi support in your dedicated Slack or Teams channel.
### One-click enrollment
We offer one-click enrollment for eligible payers. Once you submit the enrollment request, Stedi handles the entire process without any additional action from you. These payers don't require any signatures or documentation other than what is included in the enrollment request.
You can determine whether a payer is eligible for one-click enrollment by:
* Checking the [Payer Network](https://www.stedi.com/healthcare/network). Click a payer's name to view its details. Stedi lists the **Type** as **One-click** for transaction types that support one-click enrollment.
* Calling the [Payers API](/api-reference/healthcare/get-payers). The `enrollment.transactionEnrollmentProcesses.{transactionType}.type` property is set to `ONE_CLICK` for transaction types that support one-click enrollment.
### Rejected enrollments
In rare cases, the enrollment status might be set to `REJECTED` if the payer denies the enrollment request. Rejection can happen for many reasons, but the most common are:
* The provider isn't credentialed with the payer. If a payer rejects your transaction enrollment request with a message indicating the provider is "not on file" or "not recognized," it likely means the provider hasn't completed credentialing and payer enrollment with that payer. Visit [Credentialing and enrollment](/healthcare/credentialing-and-enrollment) to learn more.
* There was incorrect data in the enrollment submission.
If an enrollment is rejected, Stedi puts a note on the enrollment request explaining the reason and how to resolve it. You can review the note through the UI or API and contact Stedi support in Slack or Teams with any additional questions.
## Create enrollment requests
An enrollment request includes the provider record, the transaction type you want to enroll, the payer you want to enroll with, and a designated contact that the payer can communicate with about the enrollment. All requests go through the same high-level [enrollment process](#enrollment-process) once submitted.
If you're a provider using an [integrated account](/healthcare/integrated-accounts), you can create enrollment requests individually or through bulk CSV import. Developers can also create enrollment requests programmatically through the API.
### Individual UI submission
Creating individual enrollment requests through the Stedi portal involves two steps:
1. **Create a provider record:** Visit the [Providers page](https://portal.stedi.com/app/healthcare/providers) and click **New provider**.
2. **Create an enrollment request:** Visit the [Enrollments page](https://portal.stedi.com/app/healthcare/enrollments) and click **New enrollment**. Requests are automatically submitted to Stedi upon creation.
### Bulk CSV import
To create enrollment requests, go to the [Bulk imports page](https://portal.stedi.com/app/healthcare/enrollments/bulk) and click **New bulk import**.
The upload page contains detailed instructions for formatting the CSV file. Once you upload the file, Stedi checks for errors and flags any rows that require adjustments. You can either fix the errors and re-upload the CSV file or click **Continue anyway** to proceed with importing valid rows.
Stedi automatically does the following when importing enrollment requests from a CSV file:
* Creates provider records as needed. Stedi creates a new provider record for each unique combination of NPI and tax ID in the CSV file. For example, these two providers would be created as separate records even though they have the same name and NPI:
* `John Doe, NPI: 1999999984, Tax ID: 987654321`
* `John Doe, NPI: 1999999984, Tax ID: 123456789`
When a row in your CSV file contains an NPI and tax ID that match an
existing provider record, Stedi overwrites the existing provider record
with the information in the CSV file. Any changes (such as updated address
or contact information) aren't automatically applied to existing
enrollment requests for that provider, only to requests created after
Stedi updated the record.
* Creates and submits enrollment requests. You can check the status of each request through the [Enrollments page](https://portal.stedi.com/app/healthcare/enrollments) once the import is complete.
* Removes duplicate rows to prevent duplicate requests.
* Checks for errors. Stedi imports valid rows and skips any that contain errors. For example, if a row contains an invalid NPI, Stedi skips that row and imports the rest of the file.
#### Import status report
After importing, you can download a report that shows the status of each row in the CSV file. For example, duplicate rows are marked as `Duplicate: Enrollment already exists` in the `result` column.
Rows with errors display a clear inline error message to help you quickly make the necessary adjustments. You can fix rows with errors and re-upload the CSV file as many times as needed until all imports are successful.
### API submission
Creating enrollment requests programmatically through Stedi APIs involves two steps:
1. **Create a provider record:** Call the [Create Provider](/api-reference/healthcare/post-enrollment-create-provider) endpoint.
2. **Create an enrollment request:** Call the [Create Enrollment](/api-reference/healthcare/post-enrollment-create-enrollment) endpoint. You can create enrollment requests in `DRAFT` status first and change the status to `SUBMITTED` later when you're ready to submit them to Stedi. Stedi won't process the enrollment until it is in `SUBMITTED` status.
### Enrollment contact information
When you submit an enrollment requests, you'll need to provide two types of contact information.
**Provider contact information**
This is where the payer will send communications about the enrollment, if needed.
* The provider's name and address should match exactly what the payer has on file. Some payers reject enrollment requests with addresses that don't match their records.
* However, you may want to set the phone number or email to your own contact details. Do this when you want the payer to contact you about the enrollment instead of the provider directly.
**Submitter contact information**
This is the email address where Stedi will send updates about the enrollment. We'll use it to notify you when there are next steps and send updates on the enrollment's status.
This is called the **Person for Stedi to contact** in the Stedi portal, and it's the `userEmail` property in the Stedi API.
## Review enrollment details
You can review each enrollment request's [status](#enrollment-statuses) on the [Enrollments page](https://portal.stedi.com/app/healthcare/enrollments) in Stedi. Click any enrollment request to go to its details page. The details page includes information about the provider and payer, details about the enrollment process, and any documents associated with the enrollment.
Alternatively, you can retrieve information about enrollment requests through the [List Enrollments](/api-reference/healthcare/get-enrollment-list-enrollments) endpoint.
### Manage enrollment documents
You can download any documents associated with the enrollment from the details page, such as signed enrollment forms.
## Cancel enrollments
You can only cancel enrollment requests that are in `DRAFT` or `SUBMITTED` status. Reach out to Stedi support in Slack or Teams to cancel. Once an enrollment is canceled, Stedi sets its status to `CANCELED` and stops the enrollment process with the payer.
We can't cancel enrollments that are in `PROVISIONING` or `LIVE` status. Once an enrollment is in one of these statuses, the only way to stop 835 ERAs from coming to Stedi is to submit an enrollment through another clearinghouse.
## Notification emails
Stedi sends a notification email once per hour with a summary of enrollment request status changes. The email includes a link to each enrollment request where you can review notes, instructions, and other details.
Email notifications are sent to the address designated as the **Person for Stedi to contact** about the enrollment. This is typically the email associated with the Stedi account that created the enrollment request, and it may differ from the provider's designated contact.
If you aren't receiving notification emails as expected, contact Stedi support in Slack or Teams.
## Enrollments hub
Our network and enrollment operations team knows the nuances of each payer’s enrollment requirements and maintains a public repository of payers that require additional steps through our [Transaction Enrollments Hub](https://enrollments.stedi.com).
## Practices and facilities with multiple providers or locations
Some healthcare organizations operate multiple facilities or practices under a shared structure. This is common in hospital systems, clinic networks, or large medical groups where multiple service locations operate under the same billing entity.
Here are some best practices for enrolling practices and facilities with multiple providers or locations:
* Create a single enrollment request when the same group NPI and tax ID are used as the billing provider in claims and ERAs. You don't need to submit additional enrollment requests for individual rendering providers. When submitting claims, use the taxonomy code that matches the billing provider's credentials.
* Select a single administrative entity as the contact - don't include individual provider emails. This should be a credentialing or general inbox.
## FAQ
**Do I need to enroll through Stedi if I'm already enrolled through another clearinghouse?**
Yes. Enrollment is specific to each clearinghouse. So if a payer requires enrollment, you will need to go through the enrollment process with Stedi to begin exchanging transactions through the Stedi clearinghouse.
**What will happen to the ERAs I currently receive through a different clearinghouse?**
ERAs can only be sent to a single clearinghouse. Once you enroll for ERAs through Stedi, all ERAs from that payer to the provider you enrolled will come through Stedi. The provider will no longer receive ERAs from that payer through your previous clearinghouse.
**Does enrolling with Stedi cancel my enrollment with another clearinghouse?**
For ERAs, yes. Once you enroll for ERAs through Stedi, the payer will stop sending ERAs to your previous clearinghouse.
For claims and other types of transactions, it depends on the payer. Some payers accept claims through multiple clearinghouses or direct connections. Customer support can help answer this question for your specific payers.
**Can a provider be enrolled through multiple clearinghouses at the same time?**
Yes, for claims and eligibility checks. Some payers allow providers to submit claims and eligibility checks through multiple clearinghouses. Customer support can help answer this question for your specific payers.
No, for ERAs. As soon as an ERA enrollment in Stedi is processed with the payer, you won't receive ERAs through your previous clearinghouse.
**Can I send claims through Stedi without switching my ERA enrollments?**
Yes, you can start sending claims through Stedi without enrolling for ERAs. The ERAs will still go to your current clearinghouse. In Stedi, you'll see the claim and the 277CA claim acknowledgment from the payer, but you won't see ERAs until you switch those enrollments to Stedi.
# Support
Source: https://www.stedi.com/docs/support
***
## title: Support
We encourage you to contact us with questions, feedback, or for help using our products.
## Contact us
We make every effort to respond as soon as possible, particularly to urgent requests. For both general support requests and billing inquiries, you can contact us through the following methods:
* [Website](https://www.stedi.com/contact) for all request types
* Email [support@stedi.com](mailto:support@stedi.com) for support requests, billing questions, and/or set up a dedicated Slack or Teams channel
When you report an issue, please include the following:
* A description of the issue, including the current behavior and the expected behavior
* Your [Stedi account ID](/accounts-and-billing#accounts), if you submit through our website
* Screenshots showing the problem, when possible
# Map Transaction Output
Source: https://www.stedi.com/docs/api-reference/edi-platform/get-map-transaction-output
***
title: 'Map Transaction Output'
sidebarTitle: 'Map Transaction Output'
openapi: mappings get /mappings/{id}/map-transaction-output/{transactionId}
---------------------------------------------------------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
This endpoint returns the mapped output of a processed inbound transaction. You can use it to retrieve processed transaction data asynchronously.
## Response
The endpoint applies the specified mapping to the processed transaction and returns the fully mapped output.
This endpoint returns a 202 Accepted upon receiving the initial request and while the transaction's output is being mapped in the background. Once the mapping process completes, the endpoint returns a 302 Temporary redirect to the document download URL. Many HTTP clients will automatically follow this redirect, or have a simple follow redirects configuration to set. For instance in `curl` using the `-L` or `--location` flag will automatically follow the redirect.
In the event you cannot, or chose not to automatically follow the redirect, the body of the 302 response contains a JSON object with a key `documentDownloadUrl` which contains a temporary URL to download the document. This URL is good for 60 minutes.
## Size limits
The recommended maximum size of the transaction output document mapped with this endpoint is 150 MB in Guide JSON format (equivalent of approximately 15 MB in raw EDI).
# Retry events
Source: https://www.stedi.com/docs/api-reference/edi-platform/post-events-retry
***
title: Retry events
openapi: core post /events/{eventId}/retry
------------------------------------------
The retriggered event has a new `eventId` and appears as a separate event record in the Stedi portal. For example, if you retry a `transaction.processed.v2` event, the app shows two `transaction.processed.v2` events for the file.
Retrying individual processing events can be helpful when testing your integration. For example, you can use this approach to retrigger [Destination webhooks](/edi-platform/configure/destinations) without needing to continually reprocess the same test file.
# Create Outbound Interchange
Source: https://www.stedi.com/docs/api-reference/edi-platform/post-generate-edi
***
title: "Create Outbound Interchange"
sidebarTitle: "Outbound interchange"
openapi: core post /x12/partnerships/{partnershipId}/generate-edi
-----------------------------------------------------------------
When you call this endpoint, Stedi:
1. Generates a single EDI file containing all transactions according to the Stedi guide attached to each outbound transaction setting. This includes adding required envelope information (`ISA` and `GS` headers) and autogenerated control numbers.
2. Delivers the EDI file to your trading partner through the connection specified in the transaction settings.
## Transaction data
You must provide transaction data in [Guide JSON](/edi-platform/operate/transform-json/guide-json) format. The transaction data must be \< 5MB.
## Delivery attempts
Stedi attempts to deliver a file to all configured connections every 6 minutes for up to 3 total attempts. If it cannot deliver the file after the third attempt, it marks the file execution as `FAILED` and emits the [`file.failed.v2` event](/edi-platform/operate/event-types#file-failed). Stedi displays each delivery attempt and the failure details on the [Files](https://portal.stedi.com/app/core/file-executions) page.
## Customize generated files
You can change the timezone, time format, character set (which characters are allowed), and filename for generated files. [Learn more](/edi-platform/operate/generate-edi#timezone-and-time-format).
## Inbound processing
There is no equivalent endpoint for parsing EDI files into JSON. To parse inbound files, you or your partner can send EDI files to an SFTP/FTPS or AS2 [connection](/edi-platform/configure/trading-partners/connections), and Stedi sends the JSON payload to the configured [Destination webhook](/edi-platform/configure/destinations).
# Invoke Mapping
Source: https://www.stedi.com/docs/api-reference/edi-platform/post-invoke-mapping
***
title: "Invoke Mapping"
sidebarTitle: "Invoke mapping"
openapi: mappings post /mappings/{id}/map
-----------------------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
# Deliver Transaction Group
Source: https://www.stedi.com/docs/api-reference/edi-platform/post-transaction-group
***
title: "Deliver Transaction Group"
sidebarTitle: "Transaction group"
openapi: core post /partnerships/{partnershipId}/transaction-groups/{transactionGroupId}/generate-edi
-----------------------------------------------------------------------------------------------------
When you call this endpoint, Stedi:
1. Generates a single EDI file containing all transactions in the specified transaction group (`transactionGroupId`). This includes adding required envelope information (`ISA` and `GS` headers) and autogenerated control numbers.
2. Delivers the EDI file to your trading partner through the connection specified in the transaction settings.
You can only call this endpoint with a given `transactionGroupId` once.
Afterward, that transaction group is locked, and you must create a new
transaction group to generate another file.
## Stage transactions
You can use the [Stage Transactions API](/api-reference/edi-platform/core/stage-transactions) to store one or more transactions in a transaction group on Stedi. When you're ready to send all of the transactions in the group, you can call this endpoint to generate and deliver an EDI file to your trading partner.
## Delivery attempts
Stedi attempts to deliver a file to all configured connections every 6 minutes for up to 3 total attempts. If it cannot deliver the file after the third attempt, it marks the file execution as `FAILED` and emits the [`file.failed.v2` event](/edi-platform/operate/event-types#file-failed). Stedi displays each delivery attempt and the failure details on the [Files](https://portal.stedi.com/app/core/file-executions) page.
## Customize generated files
You can change the timezone, time format, character set (which characters are allowed), and filename for generated files. [Learn more](/edi-platform/operate/generate-edi#timezone-and-time-format).
## Inbound processing
There is no equivalent endpoint for parsing EDI files into JSON. To parse inbound files, you or your partner can send EDI files to an SFTP/FTPS or AS2 [connection](/edi-platform/configure/trading-partners/connections), and Stedi sends the JSON payload to the configured [Destination webhook](/edi-platform/configure/destinations).
This endpoint generates and delivers a fully-formed EDI file for a given transaction group. Transactions are staged in a group using the `CreateTransactionGroup` endpoint. Once a file has been generated for a given transaction group, the group can no longer be used.
# Create Outbound Transaction
Source: https://www.stedi.com/docs/api-reference/edi-platform/post-transactions
***
title: "Create Outbound Transaction"
sidebarTitle: "Outbound transaction"
openapi: core post /partnerships/{partnershipId}/transactions/{transactionSettingId}
------------------------------------------------------------------------------------
When you call the endpoint, Stedi:
1. Applies the mapping (if present) to the provided transaction data.
2. Adds [fragments](/edi-platform/fragments) from specified fragment groups (if present).
3. Generates an EDI file according to the Stedi guide attached to the [outbound transaction setting](/edi-platform/configure/trading-partners/transaction-settings#create-transaction-settings). This includes adding required envelope information (`ISA` and `GS` headers) and autogenerated control numbers.
4. Delivers the EDI file to your trading partner through the [connection](/edi-platform/configure/trading-partners/connections) specified in the outbound transaction setting.
Visit [Generate EDI](/edi-platform/operate/generate-edi) for step-by-step
instructions to format transaction data and make requests.
## Response
When you deliver a single transaction without any fragment groups, this endpoint is synchronous, and you will receive any errors. If you are using more advanced features, generation may be asynchronous. In both cases, you can use the returned `fileExecutionId` to check the status of the delivery and retrieve the execution input, output, and metadata for the generated file.
## Transaction data
The endpoint supports three ways to provide transaction data:
* **No mapping or fragments**: You provide transaction data in [Guide JSON](/edi-platform/operate/transform-json/guide-json) format. The transaction data must be \< 5MB.
* **Mapping**: You provide transaction data in the source schema format for the specified [Stedi mapping](/edi-platform/mappings). The transaction data that you want to map must be \< 4MB.
* **Fragments**: You provide the fragment wrapper in [Guide JSON](/edi-platform/operate/transform-json/guide-json) format. Visit [outbound fragments](/edi-platform/fragments/outbound-fragments) for more details and examples.
## Delivery attempts
Stedi attempts to deliver a file to all configured connections every 6 minutes for up to 3 total attempts. If it cannot deliver the file after the third attempt, it marks the file execution as `FAILED` and emits the [`file.failed.v2` event](/edi-platform/operate/event-types#file-failed). Stedi displays each delivery attempt and the failure details on the [Files](https://portal.stedi.com/app/core/file-executions) page.
## Customize generated files
You can change the timezone, time format, character set (which characters are allowed), and filename for generated files. [Learn more](/edi-platform/operate/generate-edi#timezone-and-time-format).
## Inbound processing
There is no equivalent endpoint for parsing EDI files into JSON. To parse inbound files, you or your partner can send EDI files to an SFTP/FTPS or AS2 [connection](/edi-platform/configure/trading-partners/connections), and Stedi sends the JSON payload to the configured [Destination webhook](/edi-platform/configure/destinations).
# Delete Provider
Source: https://www.stedi.com/docs/api-reference/healthcare/delete-enrollment-provider
***
openapi: enrollment delete /providers/{providerId}
title: Delete Provider
sidebarTitle: "Delete Provider"
-------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint allows you to delete providers without associated [transaction enrollments](/healthcare/transaction-enrollment). If you need to delete a provider that has associated enrollments, contact support.
# Delete Enrollment
Source: https://www.stedi.com/docs/api-reference/healthcare/delete-enrollment
***
openapi: enrollment delete /enrollments/{enrollmentId}
title: Delete Enrollment
sidebarTitle: "Delete Enrollment"
---------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint allows you to delete a [transaction enrollment](/healthcare/transaction-enrollment) that is still in `DRAFT` status. To update or delete an enrollment that is already in `SUBMITTED`, `PROVISIONING`, `LIVE`, `REJECTED`, or `CANCELED` status, contact support.
# List Enrollments
Source: https://www.stedi.com/docs/api-reference/healthcare/get-enrollment-list-enrollments
***
openapi: enrollment get /enrollments
title: List Enrollments
sidebarTitle: 'List Enrollments'
--------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint retrieves a list of all [transaction enrollments](/healthcare/transaction-enrollment) in your Stedi account.
You can filter the results by various criteria, such as a query string (fuzzy matching is supported), enrollment status, creation date, provider names, provider NPIs, provider tax IDs, and Stedi payer IDs. When a query parameter is an array, you can include it more than once in the URL to filter by multiple values.
| Query parameters | Endpoint returns |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `?providerNames=John%20Doe&providerNames=Jane%20Doe` | Enrollments associated with either John Doe or Jane Doe. |
| `?status=LIVE` | Enrollments in `LIVE` status. |
| `?filter=OS&createdFrom=2025-01-01T00:00:00Z` | - Enrollments with provider names, provider NPIs, provider tax IDs, or Stedi payer IDs containing `os` or `OS`. The search is case-insensitive, and fuzzy matching is supported.
- Enrollments created after `2025-01-01T00:00:00Z`.
|
# List Providers
Source: https://www.stedi.com/docs/api-reference/healthcare/get-enrollment-list-providers
***
openapi: enrollment get /providers
title: List Providers
sidebarTitle: 'List Providers'
------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint retrieves all of the provider records in your Stedi account. You can filter the results by the provider's name, NPI, or tax ID.
This endpoint returns only the provider record; it doesn't include information about associated [transaction enrollments](/healthcare/transaction-enrollment). To retrieve enrollment information, use the [List Enrollments](/api-reference/healthcare/get-enrollment-list-enrollments) endpoint.
# Retrieve Provider
Source: https://www.stedi.com/docs/api-reference/healthcare/get-enrollment-provider
***
openapi: enrollment get /providers/{providerId}
title: Retrieve Provider
sidebarTitle: "Retrieve Provider"
---------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint allows you to retrieve details for the specified provider.
# Retrieve Enrollment
Source: https://www.stedi.com/docs/api-reference/healthcare/get-enrollment
***
openapi: enrollment get /enrollments/{enrollmentId}
title: Retrieve Enrollment
sidebarTitle: "Retrieve Enrollment"
-----------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint retrieves details for the specified [transaction enrollment](/healthcare/transaction-enrollment).
# Poll Batch Eligibility Checks
Source: https://www.stedi.com/docs/api-reference/healthcare/get-healthcare-polling-eligibility
***
openapi: manager get /eligibility-manager/polling/batch-eligibility
title: Poll Batch Eligibility Checks
sidebarTitle: "Poll Batch Checks"
---------------------------------
This endpoint retrieves the results of asynchronous eligibility checks you submitted through the asynchronous [Batch Eligibility Checks](/api-reference/healthcare/post-healthcare-batch-eligibility) endpoint or through [CSV upload](/healthcare/batch-refresh-eligibility-checks#manual-submission) in the Stedi portal. It doesn't return results for real-time eligibility checks.
1. Call this endpoint. You can optionally add one or more query parameters to filter the results you want to retrieve.
2. The endpoint returns completed checks matching the criteria. Stedi retries checks that fail due to [payer connectivity issues](/healthcare/eligibility-troubleshooting#payer-connectivity-issues) for up to 8 hours. Therefore, it can take up to 8 hours for all checks in a batch to return results.
Each `item` in the response contains the benefits information for a completed eligibility check. Note that our documentation lists all enums officially allowed in the eligibility response. Some payers return non-compliant values, which Stedi passes through as is.
Visit [Retrieve batch results](/healthcare/batch-refresh-eligibility-checks#retrieve-batch-results) for a complete how-to guide.
## Pagination
By default, the response includes the results for up to 10 eligibility checks within a single page - each eligibility response is represented as one item in the `items` array. You can control the number of results returned per page using the `pageSize` query parameter, which accepts a value between 1 and 200.
When there are additional pages of results, the response includes the `nextPageToken` property. To retrieve the next page of results, call the endpoint with the same `batchId` and other query parameters, and set the `pageToken` query parameter to the `nextPageToken` value. Repeat this process until the response doesn't include a `nextPageToken` property.
If you set the page size to a value > 20, Stedi returns the requested batch check results in `gzip` format to reduce the size. Many common HTTP clients accept `gzip` by default, but if not, you must add the `Accept-Encoding: gzip` header to your request and resubmit.
# 277CA Report
Source: https://www.stedi.com/docs/api-reference/healthcare/get-healthcare-reports-277
***
openapi: healthcare get /change/medicalnetwork/reports/v2/{transactionId}/277
title: 277CA Report
sidebarTitle: 277 Claim Acknowledgment Report
---------------------------------------------
The 277CA claim acknowledgment indicates whether a claim was accepted or rejected and (if relevant) the reasons for rejection. This endpoint retrieves processed 277CA transactions from Stedi.
1. Call this endpoint with the `transactionId` of the 277CA you want to retrieve. You can retrieve the transaction ID through webhooks or through Stedi's API. [Learn more](/healthcare/receive-claim-responses#discover-processed-responses)
2. The endpoint returns the 277CA in JSON format.
* Visit [277CA claim status details](/healthcare/receive-claim-responses#277ca-claim-status-details) to learn which parts of the 277CA contain claim status information.
* Visit [Correlate 277CA](/healthcare/receive-claim-responses#correlate-277ca) to learn how to match 277CAs to the original claim.
# 835 ERA Report
Source: https://www.stedi.com/docs/api-reference/healthcare/get-healthcare-reports-835
***
openapi: healthcare get /change/medicalnetwork/reports/v2/{transactionId}/835
title: 835 ERA Report
---------------------
The 835 Electronic Remittance Advice (ERA) contains details about payments for specific services and explanations for any adjustments or denials. This endpoint retrieves processed 835 ERA transactions from Stedi.
1. Call this endpoint with the `transactionId` of the 835 ERA you want to retrieve. You can retrieve the transaction ID through webhooks or through Stedi's API. [Learn more](/healthcare/receive-claim-responses#discover-processed-responses)
2. The endpoint returns the 835 ERA in JSON format.
Note that the payer won't send 835 ERAs for rejected claims. If a claim is rejected in a 277CA claim acknowledgment, there's no adjudication or payment information to report.
Visit [Correlate 835 ERA](/healthcare/receive-claim-responses#correlate-835-era) to learn how to match 835 ERAs to the original claim.
## Claim status
You can't reliably determine a claim's status based on the amount paid in an 835 ERA. There are many instances in which a claim is accepted and the total amount paid is 0 dollars. For example, in Value-Based Care (VBC) scenarios, line item rates are usually 0 dollars, and providers are paid a flat rate per month or for a complete bundle of services.
Use the [Real-Time Claim Status API](/api-reference/healthcare/post-healthcare-claim-status) to check the claim's status instead.
# Insurance Discovery Check Results
Source: https://www.stedi.com/docs/api-reference/healthcare/get-insurance-discovery-results
***
openapi: healthcare get /insurance-discovery/check/v1/{discoveryId}
title: Insurance Discovery Check Results
sidebarTitle: Insurance Discovery Check Results
-----------------------------------------------
You can use this endpoint to retrieve [insurance discovery check](/healthcare/insurance-discovery) results for a particular patient asynchronously.
You can begin polling immediately after receiving a `PENDING` status response from the synchronous Insurance Discovery Check endpoint. This endpoint can take up to 120 seconds to return a response.
It's unlikely for the insurance discovery process to take more than a few minutes, so it's rare to have to poll this endpoint more than once. However, if you receive a `PENDING` status, you can poll immediately again and continue polling until the status changes to `COMPLETE.`
Note that you should only expect to retrieve checks submitted within the last 24 hours. After 24 hours, the results may no longer be available.
# Retrieve Payer
Source: https://www.stedi.com/docs/api-reference/healthcare/get-payer
***
sidebarTitle: 'Retrieve Payer'
title: Retrieve Payer
openapi: healthcare get /payer/{stediId}
----------------------------------------
You can use this endpoint to retrieve a specific payer record with the Stedi payer ID (`stediId`). You can find the Stedi payer ID for any supported payer in the [Payer Network](https://www.stedi.com/healthcare/network). Note that you must supply the Stedi payer ID - this endpoint doesn't support querying with the primary payer ID or payer ID aliases.
The payer record includes the payer's names, aliases, and supported use cases (medical or dental). It also contains supported transaction types and specifies whether [transaction enrollment](/healthcare/transaction-enrollment) is required.
# List Payers CSV
Source: https://www.stedi.com/docs/api-reference/healthcare/get-payers-csv
***
sidebarTitle: 'List Payers CSV'
title: List Payers CSV
openapi: healthcare get /payers/csv
-----------------------------------
You can use this endpoint to retrieve Payer IDs, determine which transactions each payer supports, and check whether [transaction enrollment](/healthcare/transaction-enrollment) is required for the transaction types you plan to send and receive.
You can also find a searchable list of payers in the [Payer Network](https://www.stedi.com/healthcare/network).
# List Payers JSON
Source: https://www.stedi.com/docs/api-reference/healthcare/get-payers
***
sidebarTitle: 'List Payers JSON'
title: List Payers JSON
openapi: healthcare get /payers
-------------------------------
You can use this endpoint to retrieve Payer IDs, determine which transactions each payer supports, and check whether [transaction enrollment](/healthcare/transaction-enrollment) is required for the transaction types you plan to send and receive.
You can also find a searchable list of payers in the [Payer Network](https://www.stedi.com/healthcare/network).
# CMS-1500 PDF: Business Identifier
Source: https://www.stedi.com/docs/api-reference/healthcare/get-pdf-1500-business-identifier
***
sidebarTitle: ' CMS-1500 PDF: Business Identifier'
title: 'CMS-1500 PDF: Business Identifier'
openapi: healthcare get /export/pdf
-----------------------------------
This endpoint uses a business identifier to retrieve autogenerated CMS-1500 Claim Form PDFs for submitted 837P professional claims.
1. Call this endpoint with the `businessId` query parameter set to the claim's correlation ID. The correlation ID is returned as the `claimReference.correlationId` in the synchronous response Stedi returns when you submit a professional claim.
2. The endpoint returns an array of PDFs for all claims with the specified `businessId` value. PDFs are returned as a base64 encoded string.
To view a PDF, decode the base64 string and save it to a file with a `.pdf` extension.
If you plan to send these PDFs to payers or retain them for your records, we strongly recommend visiting [CMS-1500 Claim Form PDF](/healthcare/cms-1500-claim-form-pdf) for information about how to structure claim submissions for optimal generation, the correct printer settings for generated PDFs, and general best practices.
# CMS-1500 PDF: Transaction ID
Source: https://www.stedi.com/docs/api-reference/healthcare/get-pdf-1500
***
sidebarTitle: ' CMS-1500 PDF: Transaction ID'
title: 'CMS-1500 PDF: Transaction ID'
openapi: healthcare get /export/{transactionId}/1500/pdf
--------------------------------------------------------
This endpoint uses a claim's `transactionId` to retrieve autogenerated CMS-1500 Claim Form PDFs for submitted 837P professional claims.
1. Call this endpoint with the `transactionId` path parameter set to the claim's transaction ID. This ID is included in the transaction processed event for the claim, which you can receive automatically through Stedi [webhooks](/healthcare/configure-webhooks). You can also retrieve this ID through the [Poll Transactions](/api-reference/edi-platform/core/get-pollingtransactions) endpoint or from the transaction's details page within Stedi.
2. The endpoint returns the PDF data as a base64 encoded string.
To view the PDF, decode the base64 string and save it to a file with a `.pdf` extension.
If you plan to send these PDFs to payers or retain them for your records, we strongly recommend visiting [CMS-1500 Claim Form PDF](/healthcare/cms-1500-claim-form-pdf) for information about how to structure claim submissions for optimal generation, the correct printer settings for generated PDFs, and general best practices.
# Search Payers
Source: https://www.stedi.com/docs/api-reference/healthcare/get-search-payers
***
sidebarTitle: 'Search Payers'
title: Search Payers
openapi: healthcare get /payers/search
--------------------------------------
This endpoint queries the [Payer Network](https://www.stedi.com/healthcare/network). It's especially useful when you want to embed dynamic payer search capabilities into your system or application.
1. Call this endpoint with your desired search criteria. You can search by the payer's name, [payer ID](/healthcare/supported-payers#payer-ids), or payer ID aliases. You can also filter the results by supported transaction types.
2. The endpoint returns information about matching payers, including their possible names, their primary payer ID, payer ID aliases, and supported transaction types.
The search supports fuzzy matching, which means that the results contain an array of exact (if available) and close matches.
## Results
When you specify multiple transaction filters, they are combined with AND logic, meaning payers must satisfy all specified transaction criteria to be included in results.
Stedi weights results based on text match relevance and additional factors, such as payer size, market share, and transaction volume in order to present the most likely matches first. Stedi also accounts for potential misspellings (a search for CEGNA still returns CIGNA) and transposed letters (a search for ICGNA still returns CIGNA) when searching the payer database.
## Examples
This page contains two examples of search results:
* **Basic Search**: The `SearchPayers_example1` response shows the results of a basic search for the query string "Blue Cross". The URL for this request is `https://healthcare.us.stedi.com/2024-04-01/payers/search?query=Blue%20Cross`.
* **Complex Search**: The `SearchPayers_example2` response shows the results of a more advanced search that includes a query string for "Blue Cross", plus additional query parameters that filter for payers supporting eligibility checks and real-time claim status. The URL for this request is `https://healthcare.us.stedi.com/2024-04-01/payers/search?query=Blue%20Cross&eligibilityCheck=SUPPORTED&claimStatus=SUPPORTED`. In the `stats` object, the summary counts of payers matching the search criteria are fewer than the summary counts for the basic search. This is because the advanced search only returns payers that support both eligibility checks and claim status, while the basic search returns all payers, regardless of the transaction types they support.
Both examples are truncated for brevity to show only one payer matching the results (Blue Cross Blue Shield of Michigan).
# Eligibility mock requests
Source: https://www.stedi.com/docs/api-reference/healthcare/mock-requests-eligibility-checks
***
title: Eligibility mock requests
sidebarTitle: "Testing: Send mock requests"
-------------------------------------------
When you submit the following requests to the [Real-Time Eligibility Check](/api-reference/healthcare/post-healthcare-eligibility) endpoint with a test API key, Stedi returns mock benefits data from the specified payer you can use for testing.
You can also submit these mock requests through the [New eligibility check](https://portal.stedi.com/app/healthcare/checks/create) form in the UI when **Test mode** is enabled.
Mock requests are free for testing purposes and won't incur any charges in
your Stedi account.
## Test API key
When submitting these mock requests to the API, you must use a test [Stedi API key](/api-reference#creating-an-api-key) for authentication. When using a test API key, you can only send the following mock requests to the endpoint. Stedi returns an error if you try to send production data with a test API key.
## API clients
You may want to use an API client to make testing and debugging easier.
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.
Visit [API clients](/api-reference#api-clients) for a list of recommended clients you can use instead.
## Medical - Active coverage
Request notes:
* `encounter`: Only service type code `30` is supported.
* `provider`: You can use any organization name and any NPI, as long as it passes [check digit validation](https://www.cms.gov/Regulations-and-Guidance/Administrative-Simplification/NationalProvIdentStand/Downloads/NPIcheckdigit.pdf). To generate a dummy NPI, you can use [this free tool](https://jsfiddle.net/alexdresko/cLNB6).
* `subscriber`: You must use the exact values in the test request. Other birth dates, first names, last names, member IDs, and Social Security Numbers return errors.
### Dependent
Each of these examples represent an eligibility check for a dependent. An individual qualifies as a dependent for eligibility checks when they are listed as a dependent on the subscriber's insurance plan AND the payer cannot uniquely identify them through information outside the subscriber's policy.
These example requests follow best practices for structuring eligibility checks. Specifically, all requests include the dependent's information, including their date of birth, in the `dependents` array. Some payers may allow different structures, such as sending the dependent's information in the `subscriber` object with the subscriber's member ID. However, we recommend following the guidance outlined in the [Real-Time Eligibility Check](/api-reference/healthcare/mock-requests-eligibility-checks#dependent) endpoint documentation for the most reliable results across all payers.
The way dependent information is included in the response varies by payer. Some contain the dependent's information in the `subscriber` object. Some include the actual subscriber's information in the `subscriber` object and the dependent's information in the `dependents` array.
**Aetna**
In this example, the dependent Jordan is the subscriber John's child. Jordan's information is returned in the `dependents` array in the response.
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Aetna
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "60054",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"memberId": "AETNA9wcSu"
},
"dependents": [
{
"firstName": "Jordan",
"lastName": "Doe",
"dateOfBirth": "20010714"
}
],
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**Anthem Blue Cross Blue Shield of CA**
In this example, the dependent John is the subscriber Jane's spouse. John's information is returned in the `dependents` array in the response.
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Anthem BCBSCA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "040",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"memberId": "CGMBCBSCA123"
},
"dependents": [
{
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "19750101"
}
],
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**Blue Cross and Blue Shield of Texas**
In this example, the dependent Jane is the subscriber John's child. Jane's information is returned in the `dependents` array in the response.
{/* schema:EligibilityCheckRequestContent */}
```bash test request for BCBSTX
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "G84980",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"memberId": "A2CBCBSTX123"
},
"dependents": [
{
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "20150101"
}
],
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**Cigna**
In this example, the dependent Jordan is the subscriber's child. In the response, Jordan is returned in the `subscriber` object with no `dependents` array, even though they are a dependent.
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Cigna
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"memberId": "CIGNAJTUxNm"
},
"dependents": [
{
"firstName": "Jordan",
"lastName": "Doe",
"dateOfBirth": "20150920"
}
],
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**Oscar Health**
In this example, the dependent Jane is the subscriber John's child. Jane's information is returned in the `dependents` array in the response.
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Oscar Health
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "OSCAR",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"memberId": "OSCAR123456"
},
"dependents": [
{
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "20010101"
}
],
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**UnitedHealthcare**
In this example, the dependent Jane is the subscriber John's spouse. Jane's information is returned in the `dependents` array in the response.
{/* schema:EligibilityCheckRequestContent */}
```bash test request for UnitedHealthcare
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"memberId": "UHC202649"
},
"dependents": [
{
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19521121"
}
],
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
### Subscriber only
The following examples request benefits information for the subscriber only. The subscriber's information is sent in the `subscriber` object in the request. The payer's response contains the subscriber's information in the `subscriber` object and doesn't include any dependent information.
**Aetna**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Aetna
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "60054",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "20040404",
"memberId": "AETNA12345"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**Ambetter**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Ambetter
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "68069",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "19940404",
"memberId": "AMBETTER123"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**Cigna**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for CIGNA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"controlNumber":"123456789",
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "James",
"lastName": "Jones",
"dateOfBirth": "19910202",
"memberId": "23456789100"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
{/* schema:EligibilityCheckRequestContent */}
```bash test request for CIGNA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Rolando",
"lastName": "Arrojo",
"dateOfBirth": "19710102",
"memberId": "5643296"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
{/* schema:EligibilityCheckRequestContent */}
```bash test request for CIGNA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Rod",
"lastName": "Beck",
"dateOfBirth": "19720203",
"memberId": "R5TJR4HR4H"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
{/* schema:EligibilityCheckRequestContent */}
```bash test request for CIGNA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "David",
"lastName": "Cone",
"dateOfBirth": "19730304",
"memberId": "5642296"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
{/* schema:EligibilityCheckRequestContent */}
```bash test request for CIGNA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Frank",
"lastName": "Castillo",
"dateOfBirth": "19750405",
"memberId": "FTRJRG3254"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
{/* schema:EligibilityCheckRequestContent */}
```bash test request for CIGNA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Casey",
"lastName": "Fossum",
"dateOfBirth": "19760506",
"memberId": "5641296"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
{/* schema:EligibilityCheckRequestContent */}
```bash test request for CIGNA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "62308",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Rich",
"lastName": "Garces",
"dateOfBirth": "19770607",
"memberId": "DHW5445"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**Humana**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Humana
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "61101",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19750505",
"memberId": "HUMANA123"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**Kaiser Permanente Northern California**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Kaiser Permanente
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "KSRCN",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "20020202",
"memberId": "KAISER123456"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**National Centers for Medicare & Medicaid Services (CMS)**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for CMS
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "CMS",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19550505",
"memberId": "CMS12345678"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
**UnitedHealthcare**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19710101",
"memberId": "UHC123456"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
### MBI lookup for CMS checks
You must include the patient's Medicare Beneficiary Identifier (MBI) in every eligibility check you submit to the Centers for Medicare and Medicaid Services ([Payer ID: CMS](https://www.stedi.com/healthcare/network?page=0\&search=CMS\&entry=JDNSN&__hstc=181257784.360aac417a3f93a63ca63bf29197fe1f.1727971380232.1743632880282.1743697406042.288&__hssc=181257784.12.1743697406042&__hsfp=2436917072)). When patients don’t know their MBI, you can use Stedi’s eligibility APIs to perform an MBI lookup using their Social Security Number instead. Visit [MBI lookup](/healthcare/mbi-lookup#enrollment) for more information.
{/* schema:EligibilityCheckRequestContent */}
```bash
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key ' \
--header 'Content-Type: application/json' \
--data '{
"controlNumber": "112233445",
"tradingPartnerServiceId": "MBILU",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"lastName": "Doe",
"dateOfBirth": "19550505",
"ssn": "123456789"
},
"encounter": {
"serviceTypeCodes": [
"30"
]
}
}'
```
## Medical - Inactive coverage
The following example requests benefits information for the subscriber.
**UnitedHealthcare**
{/* schema:EligibilityCheckRequestContent */}
```bash request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Provider Name",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19710101",
"memberId": "UHCINACTIVE"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
## Dental
The following example requests benefits information for the subscriber.
Request notes:
* `encounter`: Only service type code `35` is supported.
* `provider`: You can use any organization name and any NPI, as long as it passes [check digit validation](https://www.cms.gov/Regulations-and-Guidance/Administrative-Simplification/NationalProvIdentStand/Downloads/NPIcheckdigit.pdf). To generate a dummy NPI, you can use [this free tool](https://jsfiddle.net/alexdresko/cLNB6).
* `subscriber`: You must use the exact values in the test request. Other birthdates, first names, last names, and member IDs return errors.
**Ameritas**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Ameritas
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "100925",
"provider": {
"firstName": "Plaque",
"lastName": "Penguin",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Falcon",
"lastName": "Dent",
"dateOfBirth": "19850607",
"memberId": "007007007"
},
"encounter": {
"serviceTypeCodes": ["35"]
}
}'
```
**Anthem Blue Cross Blue Shield of CA**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for BCBSCA
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "84103",
"provider": {
"organizationName": "One",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Aardvark",
"lastName": "Dent",
"dateOfBirth": "19701212",
"memberId": "AFK987654321"
},
"encounter": {
"serviceTypeCodes": ["35"]
}
}'
```
**Cigna**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Cigna
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "59-1031071",
"provider": {
"organizationName": "One",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jaguar",
"lastName": "Dent",
"dateOfBirth": "19960505",
"memberId": "U3141592653"
},
"encounter": {
"serviceTypeCodes": ["35"]
}
}'
```
**Metlife**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for Metlife
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "101256",
"provider": {
"organizationName": "One",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Elephant",
"lastName": "Dent",
"dateOfBirth": "19840229",
"memberId": "88877788"
},
"encounter": {
"serviceTypeCodes": ["35"]
}
}'
```
**UnitedHealthcare**
{/* schema:EligibilityCheckRequestContent */}
```bash test request for UnitedHealthcare
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "52133",
"provider": {
"organizationName": "One",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Beaver",
"lastName": "Dent",
"dateOfBirth": "19690628",
"memberId": "404404404"
},
"encounter": {
"serviceTypeCodes": ["35"]
}
}'
```
## Common AAA errors
The following requests return mock data for the most common Payer `AAA` errors. Visit [Eligibility troubleshooting](/healthcare/eligibility-troubleshooting) for a complete list of AAA error codes, other common eligibility check issues, and recommended resolution steps.
### 42 - Unable to respond at current time
The following example request returns a `42` AAA error code, indicating that the payer is unable to respond at the current time. This is typically a temporary issue with the payer’s system, but it can also be an extended outage or the payer throttling your requests.
{/* schema:EligibilityCheckRequestContent */}
```bash request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Medical Provider",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "20010101",
"memberId": "UHCAAA42"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
### 43 - Invalid/Missing Provider Identification
The following example request returns a `43` AAA error code. This error can occur if provider's NPI is not registered with the payer, the provider's NPI is not registered *correctly* with the payer, or the payer requires an agreement.
{/* schema:EligibilityCheckRequestContent */}
```bash request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Medical Provider",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19700101",
"memberId": "UHCAAA43"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
### 72 - Invalid/Missing Subscriber/Insured ID
The following example request returns a `72` AAA error code. This error can occur if the subscriber member ID was incorrect in the request, the request does not meet the payer's requirements for the subscriber ID, or there is another unidentified error in the request data.
{/* schema:EligibilityCheckRequestContent */}
```bash request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Medical Provider",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "19900101",
"memberId": "UHCAAA72"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
### 73 - Invalid/Missing Subscriber/Insured Name
The following example request returns a `73` AAA error code. This error can occur if an incorrect subscriber name was submitted, the subscriber name was missing, the subscriber name was spelled incorrectly, or the request doesn't meet the payer's requirements for the subscriber's name.
{/* schema:EligibilityCheckRequestContent */}
```bash request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Medical Provider",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "19900101",
"memberId": "UHCAAA73"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
### 75 - Subscriber/Insured Not Found
The following example request returns a `75` AAA error code. This error occurs when the payer can't find the subscriber in their database. You should verify the subscriber details and try sending different combinations of `firstName`, `lastName`, `dateOfBirth`, and `memberId`. Note that not all search combinations are supported by all payers.
{/* schema:EligibilityCheckRequestContent */}
```bash request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Medical Provider",
"npi": "1999999984"
},
"subscriber": {
"firstName": "Jane",
"lastName": "Doe",
"dateOfBirth": "19900101",
"memberId": "UHCAAA75"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
### 79 - Invalid Participant Identification
The following example request returns a `79` AAA error code. This error occurs when there is a problem connecting with the payer. You should contact Stedi support for assistance.
{/* schema:EligibilityCheckRequestContent */}
```bash request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "87726",
"provider": {
"organizationName": "Medical Provider",
"npi": "1999999984"
},
"subscriber": {
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "19700101",
"memberId": "UHCAAA79"
},
"encounter": {
"serviceTypeCodes": ["30"]
}
}'
```
## Test the Stedi Agent
The [Stedi Agent](/healthcare/eligibility-manager#stedi-agent) resolves recoverable eligibility check errors automatically with the same best practices our Support team uses for troubleshooting. You can run the following mock eligibility check to evaluate the Stedi Agent.
{/* schema:EligibilityCheckRequestContent */}
```bash request for UHC
curl --request POST \
--url 'https://healthcare.us.stedi.com/2024-04-01/change/medicalnetwork/eligibility/v3' \
--header 'Authorization: Key {test_api_key}' \
--header 'Content-Type: application/json' \
--data '{
"tradingPartnerServiceId": "STEDI",
"subscriber": {
"lastName": "Prohas",
"memberId": "23051322",
"firstName": "Bernie"
},
"provider": {
"organizationName": "STEDI",
"npi": "1999999984"
}
}'
```
This check is designed to fail so you can watch the agent resolve issues in real time. Specifically, it returns `AAA` error `73` (Invalid/Missing Subscriber/Insured Name).
Once the check is complete, you can use it to test the Stedi Agent's troubleshooting capabilities:
1. Go to the [Eligibility searches](https://portal.stedi.com/app/healthcare/eligibility) page in your Stedi account.
2. Toggle **Test mode** to **ON**.
3. Click the failed mock eligibility check to review its details.
4. Click **Resolve with Stedi Agent**. The agent runs in **Debug view** to fix the error and eventually produce a successful mock eligibility response.
# Coordination of Benefits Check
Source: https://www.stedi.com/docs/api-reference/healthcare/post-coordination-of-benefits
***
openapi: healthcare post /coordination-of-benefits
title: Coordination of Benefits Check
-------------------------------------
Coordination of benefits (COB) checks help you determine whether patients are covered by multiple health plans, whether coverage overlap requires coordination of benefits, and each payer's responsibility for payment (primacy).
1. Call this endpoint with a JSON payload. Each check **must** be for a Stedi-supported payer with which the patient has coverage. Visit the [Payer Network](https://www.stedi.com/healthcare/network?filter=eyJ0cmFuc2FjdGlvbkZpbHRlcnMiOnsiMjcwIjp7fSwiMjc2Ijp7fSwiODM1Ijp7fSwiODM3UCI6e30sIjgzN0kiOnt9LCI4MzdEIjp7fSwiQ09CIjp7ImlzU3VwcG9ydGVkIjp0cnVlfSwiMjc1VSI6e319LCJjb3ZlcmFnZVR5cGVzIjpbXX0%3D) for a complete list of supported payers.
2. Stedi searches a national database containing 245+ million patient coverage records from 45+ health plans, ASOs, TPAs, and others, including participation from the vast majority of national commercial health plans. Data is updated weekly to ensure accuracy.
3. The endpoint returns information about the patient's active health plans, the responsibility sequence number for each payer if available (such as primary or secondary), and whether coordination of benefits is required.
Visit [Coordination of benefits checks](/healthcare/coordination-of-benefits) for a full how-to guide.
# Create Enrollment
Source: https://www.stedi.com/docs/api-reference/healthcare/post-enrollment-create-enrollment
***
openapi: enrollment post /enrollments
title: Create Enrollment
sidebarTitle: 'Create Enrollment'
---------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint allows you to submit a [transaction enrollment](/healthcare/transaction-enrollment) request for a specific provider. You must create one enrollment request for each transaction type. For example, you would create three separate requests to enroll a provider for 837P claims (professional), 270 real-time eligibility checks, and 835 ERAs (claim payments).
1. Add the provider's details through either the [Providers page](https://portal.stedi.com/app/healthcare/enrollments) or the [Create Provider](/api-reference/healthcare/post-enrollment-create-provider) endpoint.
2. Call this endpoint to create the enrollment request. Set the `status` property to `DRAFT` for test enrollments. Set the `status` property to `SUBMITTED` when you're ready for Stedi to begin processing the request.
3. The endpoint returns summary information about the enrollment request.
Once the status is set to `SUBMITTED`, Stedi begins processing the enrollment request. You can track its progress through the Stedi portal or the API.
## Contacts
You must add a contact to an enrollment request. This is where the payer will send communications about the enrollment, if needed.
* The provider's name and address should match exactly what the payer has on file. Some payers reject enrollment requests with addresses that don't match their records.
* However, you may want to set the phone number or email to your own contact details. Do this when you want the payer to contact you about the enrollment instead of the provider directly.
# Create Provider
Source: https://www.stedi.com/docs/api-reference/healthcare/post-enrollment-create-provider
***
openapi: enrollment post /providers
title: Create Provider
sidebarTitle: 'Create Provider'
-------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint allows you to create a provider record with the details required for [transaction enrollment](/healthcare/transaction-enrollment).
1. Call this endpoint with the provider's details.
2. The endpoint returns the created provider record, including the provider `id`, which you'll need when creating enrollment requests.
You can now add the provider to one or more transaction enrollment requests.
All providers you create through this endpoint are available on the [Providers page](https://portal.stedi.com/app/healthcare/providers) for you to review and manage.
## Contacts
You can add one or more contacts to a provider record. This is where the payer will send communications about the enrollment, if needed.
* The provider's name and address should match exactly what the payer has on file. Some payers reject enrollment requests with addresses that don't match their records.
* However, you may want to set the phone number or email to your own contact details. Do this when you want the payer to contact you about the enrollment instead of the provider directly.
# Update Enrollment
Source: https://www.stedi.com/docs/api-reference/healthcare/post-enrollment-update-enrollment
***
openapi: enrollment post /enrollments/{enrollmentId}
title: Update Enrollment
sidebarTitle: "Update Enrollment"
---------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint allows you to update enrollments that are still in `DRAFT` status. If you need to make changes to an enrollment that is already in `SUBMITTED`, `PROVISIONING`, `LIVE`, `REJECTED`, or `CANCELED` status, contact support.
Calling this endpoint completely overwrites the previous request record. You **must** provide all the information for the enrollment in the request, not just the properties you want to update.
# Update Provider
Source: https://www.stedi.com/docs/api-reference/healthcare/post-enrollment-update-provider
***
openapi: enrollment post /providers/{providerId}
title: Update Provider
sidebarTitle: "Update Provider"
-------------------------------
This is a **beta** endpoint. We may make backwards incompatible changes.
This endpoint allows you to update information for an existing provider. For example, you may want to add an additional contact.
Please note:
* Calling this endpoint completely overwrites the previous request record. You **must** provide all the information for the provider in the request, not just the properties you want to update.
* Updating a provider record doesn't affect associated enrollments that are in `SUBMITTED`, `PROVISIONING` or `LIVE` status. If you need to update the provider details for an enrollment with these statuses, contact support.
# Batch Eligibility Check
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-batch-eligibility
***
openapi: manager post /eligibility-manager/batch-eligibility
title: Batch Eligibility Check
------------------------------
You may want to periodically conduct asynchronous batch eligibility checks for your entire patient population or a subset of patients, such as those who have active care plans or who have future services scheduled. These data refreshes allow you to proactively reach out to patients when they lose or change coverage.
* Call this endpoint with a JSON payload containing one or more eligibility checks. You can submit up to 1,000 individual eligibility checks within a single batch, and you can submit as many batches as you need to process.
* The endpoint returns a synchronous response containing a `batchId` that you can use to retrieve the results of these checks later, using the [Poll Batch Eligibility Checks](/api-reference/healthcare/get-healthcare-polling-eligibility) endpoint.
* Stedi translates each eligibility check included in the request to the X12 270 EDI format and sends it to the appropriate payer.
Visit [Batch refresh checks](/healthcare/batch-refresh-eligibility-checks) for a complete how-to guide.
## Start with real-time checks
Batch checks have a longer feedback cycle than real-time checks because you don’t receive the payer’s response immediately. That’s why we strongly recommend starting with real-time checks when integrating with a new payer or working with eligibility checks for the first time. To perform synchronous eligibility checks, use the [Real-Time Eligibility Check](/api-reference/healthcare/post-healthcare-eligibility) endpoint.
# Real-Time Claim Status Raw X12
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-claim-status-raw-x12
***
openapi: healthcare post /change/medicalnetwork/claimstatus/v2/raw-x12
title: Real-Time Claim Status Raw X12
-------------------------------------
You may need to submit a 276 real-time claim status request when you don’t receive a 277CA or 835 ERA response from the payer within your expected timeframe. This endpoint is ideal if you have an existing system that generates X12 EDI files and you want to send them through Stedi.
1. Call this endpoint with a payload in [276 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/claim-status-request-x212/01GRYB6A4XEJQ61Y2K2KT606E5). Providing too much information can negatively affect the results. For best results, you should start with our [recommended base request](/healthcare/check-claim-status#x12-base-request).
2. Stedi validates the EDI and sends the transaction to the payer.
3. The endpoint returns a synchronous 277 claim status response from the payer in JSON format. The response contains information about the claims matching the criteria you provided in the request and their current status.
The response may contain information about more than one claim, if the payer has multiple claims on file that match the information you provided.
Visit [Check claim status](/healthcare/check-claim-status) for a complete how-to guide.
# Real-Time Claim Status JSON
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-claim-status
***
openapi: healthcare post /change/medicalnetwork/claimstatus/v2
title: Real-Time Claim Status JSON
----------------------------------
You may need to submit a 276 real-time claim status request when you don't receive a 277CA claim acknowledgment or 835 Electronic Remittance Advice (ERA) response from the payer within your expected timeframe.
1. Call this endpoint with a JSON payload. Providing too much information can negatively affect the results. For best results, you should start with our [recommended base request](/healthcare/check-claim-status#json-base-request).
2. Stedi generates the X12 276 EDI transaction and sends it to the payer.
3. The endpoint returns a synchronous 277 claim status response from the payer in JSON format. The response contains information about the claims matching the criteria you provided in the request and their current status.
The response may contain information about more than one claim, if the payer has multiple claims on file that match the information you provided.
Visit [Check claim status](/healthcare/check-claim-status) for a complete how-to guide and more request/response examples.
# Professional Claims (837P) Raw X12
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-claims-raw-x12
***
openapi: healthcare post /change/medicalnetwork/professionalclaims/v3/raw-x12-submission
title: Professional Claims (837P) Raw X12
sidebarTitle: Professional Claims Raw X12
-----------------------------------------
This endpoint is ideal if you have an existing system that generates X12 EDI files and you want to send them through Stedi.
1. Call this endpoint with a payload in [837 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-professional-x222a1/01HR60MDFAGCSEJNKY8J38867Y).
2. Stedi validates the EDI and sends the claim to the payer.
3. The endpoint returns a response from Stedi in JSON format containing information about the claim you submitted and whether the submission was successful.
Visit [Submit professional claims](/healthcare/submit-professional-claims) for a full how-to guide.
## CMS-1500 Claim Form PDF
When you submit a professional claim, Stedi automatically generates a [1500 claim form](https://www.nucc.org/index.php/1500-claim-form-mainmenu-35) PDF. If you plan to send these PDFs to payers or retain them for your records, we strongly recommend reviewing the [CMS-1500 claim form PDF](/healthcare/cms-1500-claim-form-pdf) documentation to learn how to structure claim submissions for optimal generation, the correct printer settings for generated PDFs, and general best practices.
# Professional Claims (837P) JSON
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-claims
***
openapi: healthcare post /change/medicalnetwork/professionalclaims/v3/submission
title: Professional Claims (837P) JSON
sidebarTitle: Professional Claims JSON
--------------------------------------
This endpoint sends 837P professional claims to payers.
1. Call this endpoint with a JSON payload.
2. Stedi translates your request to the X12 837 EDI format and sends it to the payer.
3. The endpoint returns a response from Stedi in JSON format containing information about the claim you submitted and whether the submission was successful.
Visit [Submit professional claims](/healthcare/submit-professional-claims) for a full how-to guide.
## CMS-1500 Claim Form PDF
When you submit a professional claim, Stedi automatically generates a [1500 claim form](https://www.nucc.org/index.php/1500-claim-form-mainmenu-35) PDF. If you plan to send these PDFs to payers or retain them for your records, we strongly recommend reviewing the [CMS-1500 claim form PDF](/healthcare/cms-1500-claim-form-pdf) documentation to learn how to structure claim submissions for optimal generation, the correct printer settings for generated PDFs, and general best practices.
# Create Claim Attachment JSON
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-create-claim-attachment
***
openapi: claims post /claim-attachments/file
title: Create Claim Attachment JSON
-----------------------------------
This endpoint is in **beta** and is subject to change.
This endpoint returns a pre-signed URL that you can use to upload a claim attachment file to Stedi. You must complete this step before you can submit an 837 claim with an unsolicited 275 claim attachment.
1. Call this endpoint to initiate the file upload process.
2. The endpoint returns a unique identifier for the attachment file (`attachmentId`) and a pre-signed URL (`uploadURL`). Retain the `attachmentId` so you can use it when submitting the attachment to the payer.
You only need to complete this step when submitting claims through Stedi's JSON APIs. If your system already generates X12 EDI, you can send attachments directly through the [Submit Claim Attachment (275) Raw X12](/api-reference/healthcare/post-healthcare-submit-claim-attachment-raw-x12) endpoint instead.
This endpoint only supports [unsolicited attachments](/healthcare/submit-claim-attachments#solicited-vs-unsolicited-attachments).
Visit [Claim attachments](/healthcare/submit-claim-attachments#submit-claim-attachments-275) for a full how-to guide.
# Dental Claims Raw X12
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-dental-claims-raw-x12
***
openapi: healthcare post /dental-claims/raw-x12-submission
title: Dental Claims Raw X12
----------------------------
This endpoint is ideal if you have an existing system that generates X12 EDI files and you want to send them through Stedi.
1. Call this endpoint with a payload in [837 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-dental-x224a3/01GRYB6G91ZX6R1XAFGBMRTBBW).
2. Stedi validates the EDI and sends the claim to the payer.
3. The endpoint returns a response from Stedi in JSON format containing information about the claim you submitted and whether the submission was successful.
Visit [Submit dental claims](/healthcare/submit-dental-claims) for a full how-to guide.
# Dental Claims JSON
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-dental-claims
***
openapi: healthcare post /dental-claims/submission
title: Dental Claims JSON
-------------------------
This endpoint sends 837D dental claims to payers.
1. Call this endpoint with a JSON payload.
2. Stedi translates your request to the X12 837 EDI format and sends it to the payer.
3. The endpoint returns a response from Stedi in JSON format containing information about the claim you submitted and whether the submission was successful.
Visit [Submit dental claims](/healthcare/submit-dental-claims) for a full how-to guide.
# Real-Time Eligibility Check Raw X12
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-eligibility-raw-x12
***
openapi: healthcare post /change/medicalnetwork/eligibility/v3/raw-x12
title: Real-Time Eligibility Check Raw X12
------------------------------------------
Real-time eligibility checks are ideal for in-person patient visits, telehealth appointments, and other scenarios where you need immediate information about a patient's coverage. This endpoint is ideal if you have an existing system that generates X12 EDI files and you want to send them through Stedi.
1. Call this endpoint with payload in [270 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-inquiry-x279a1/01GRYB6GTDJ4MEP5Z16CGMQWT6). Note that the request must include `BHT03` (Submitter Transaction Identifier) and the Payer ID in `Loop 2100A NM109`. We recommend reviewing the requirements for a [basic eligibility request](/healthcare/send-eligibility-checks#body---x12-edi).
2. Stedi validates the EDI and sends the eligibility check to the payer.
3. The endpoint returns a synchronous response from the payer in both JSON and raw X12 EDI format. The response contains the patient's eligibility and benefits information. Note that our documentation lists all enums officially allowed in the eligibility response. Some payers return non-compliant values, which Stedi passes through as is.
Visit [Real-time eligibility checks](/healthcare/send-eligibility-checks) for a complete how-to guide.
# Real-Time Eligibility Check SOAP
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-eligibility-soap
Submit real-time eligibility checks over SOAP using the CAQH CORE vC2.2.0 XML Schema
***
openapi: soap post /2025-06-01/protocols/caqh-core
title: Real-Time Eligibility Check SOAP
description: "Submit real-time eligibility checks over SOAP using the CAQH CORE vC2.2.0 XML Schema"
apiNodes:
authNode: false
parameterNode: false
bodyNode: false
responseNode: false
callbacksNode: false
--------------------
Real-time eligibility checks are ideal for in-person patient visits, telehealth appointments, and other scenarios where you need immediate information about a patient’s coverage. This endpoint is ideal when you must meet CAQH Core Connectivity Safe Harbor requirements or integrate with systems requiring CAQH CORE-compliant SOAP connectivity.
1. Call this endpoint with a request in XML format. The XML must conform to the [CAQH CORE vC2.2.0 XML Schema](https://www.caqh.org/core/connectivity). The `Payload` element must contain a valid eligibility check in [270 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-inquiry-x279a1/01GRYB6GTDJ4MEP5Z16CGMQWT6). We recommend reviewing the requirements for a [basic eligibility request](/healthcare/send-eligibility-checks#body---x12-edi).
2. Stedi validates your eligibility check and sends it to the payer.
3. The endpoint returns a synchronous SOAP response in [XML format](#response). It contains the full [271 X12 EDI](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-response-x279a1/01GS66YHZPB37ABF34DBPSR213) response from the payer containing the patient's eligibility and benefits information.
Visit [Real-time eligibility checks](/healthcare/send-eligibility-checks) for
a full how-to guide and
[Troubleshooting](/healthcare/eligibility-troubleshooting#soap-requests) for
SOAP-specific errors and resolutions.
## Request
The request payload must be XML that conforms to the [CAQH CORE vC2.2.0 XML Schema](https://www.caqh.org/core/connectivity). It consists of three main parts: the envelope, the header, and the body.
```xml
...
...
```
### Envelope
The SOAP `Envelope` element wraps both the header and body. It defines the message structure according to the SOAP specification.
```xml
```
`Envelope` must declare the following namespaces:
| Namespace declaration | Required | Description |
| --------------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
| `xmlns:soapenv` | Yes | Declares the XML namespace for the SOAP envelope. Must be set to `http://www.w3.org/2003/05/soap-envelope`. |
| `xmlns:cor` | Yes | Declares the XML namespace for CAQH CORE rules. Must be set to `http://www.caqh.org/SOAP/WSDL/CORERule2.2.0.xsd`. |
### Header
The `Header` element specifies the WS-Security namespace (`wsse`) and contains the required credentials for authentication.
```xml
STEDI-ACCOUNT-ID
STEDI-API-KEY
```
`Header` must include the following elements:
| Element | Required | Description |
| --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `wsse:Security` | Yes | The parent container for the security token. It includes: - The `soapenv:mustUnderstand` attribute, set to `true`.
- The `xmlns:wsse` namespace declaration, set to `http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd`
- The `xmlns:wsu` namespace declaration, set to `http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd`
|
| `wsse:Username` | Yes | Set this to your **Stedi Account ID**. You can find your account ID at the end of any Stedi portal URL. For example, in `https://portal.stedi.com/app/healthcare/eligibility?account=1111-33333-55555`, the account ID is `1111-33333-55555`. |
| `wsse:Password` | Yes | Set this to your **API Key**. You can create and manage API keys from the [API Keys page](https://portal.stedi.com/app/settings/api-keys) in the Stedi portal. |
### Body
The `Body` element contains the request details, and it must conform to the [CAQH CORE XML Schema vC2.2.0](https://www.caqh.org/core/connectivity).
```xml
X12_270_Request_005010X279A1
RealTime
YOUR-PAYLOAD-ID
2007-08-30T10:20:34.000Z
SENDER-ID
RECEIVER-ID
2.2.0
~GS*HS*SENDERGS*RECEIVERGS*20231106*140631*000000001*X*005010X279A1~ST*270*1234*005010X279A1~BHT*0022*13*10001234*20240321*1319~HL*1**20*1~NM1*PR*2*ABCDE*****PI*11122~HL*2*1*21*1~NM1*1P*2*ACME HEALTH SERVICES*****SV*1999999984~HL*3*2*22*0~TRN*1*11122-12345*1234567890~NM1*IL*1*JANE*DOE****MI*123456789~DMG*D8*19000101~DTP*291*D8*20240108~EQ*MH~SE*13*1234~GE*1*000000001~IEA*1*000000001~]]>
```
`Body` must include the following elements:
| Element | Required | Description |
| ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PayloadType` | Yes | The type of transaction. Must be set to `X12_270_Request_005010X279A1`. |
| `ProcessingMode` | Yes | The processing mode. Must be set to `RealTime`. |
| `PayloadID` | Yes | A unique identifier for the request. Must be a valid UUID. |
| `TimeStamp` | Yes | UTC time in ISO 8601 format, such as `2024-07-28T12:00:00Z`. |
| `SenderID` | Yes | An identifier for the transaction sender.- Can be up to 50 characters.
- Set this to the value you plan to use in the eligibility check's `ISA06` (Interchange Sender ID) element.
|
| `ReceiverID` | Yes | An identifier for the transaction receiver. - Can be up to 50 characters.
- Set this to the value you plan to use in the eligibility check's `ISA08` (Interchange Receiver ID) element.
|
| `CORERuleVersion` | Yes | The CAQH CORE rule version. Must be set to `2.2.0`. |
| `Payload` | Yes | The X12 EDI 270 eligibility check wrapped in ``.- Must conform to [270 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-inquiry-x279a1/01GRYB6GTDJ4MEP5Z16CGMQWT6).
- We recommend reviewing the requirements for a [basic eligibility request](/healthcare/send-eligibility-checks#body---x12-edi).
|
## Response
The response is a SOAP message, and the structure is similar to the request. The `Payload` element typically contains the payer's X12 EDI 271 response. However, if you send a request that fails X12 EDI validation, it will contain a 999 Implementation Acknowledgment indicating the errors.
```xml
X12_271_Response_005010X279A1
RealTime
f81d4fae-7dec-11d0-a765-00a0c91e6b12
2025-08-06T22:23:50Z
RECEIVER_ID
STEDI
2.2.0
~GS*HB*STEDI*117151744*20240326*111000*1*X*005010X279A1~ST*271*1001*005010X279A1~BHT*0022*11*01J2VZA127GH93JT74HJU*20240326*1514~HL*1**20*1~NM1*PR*2*ABCDE*****FI*111000123~PER*IC**TE*123456789*UR*website.company.com~HL*2*1*21*1~NM1*1P*2*ACME HEALTH SERVICES*****XX*1999999984~HL*3*2*22*0~NM1*IL*1*DOE*JANE*A***MI*123456789~REF*6P*123456789*ABCDE~REF*Q4*123456789~N3*1234 FIRST ST~N4*NEW YORK*WV*123451111~DMG*D8*19000101*F~INS*Y*18*001*25~DTP*356*D8*20220102~DTP*346*D8*20240101~DTP*347*D8*20241231~EB*1**30**Open Access Plus~MSG*Complete Care Management~EB*G*FAM*30***23*6000.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*FAM*30***23*500.00*****Y~MSG*Includes services provided by Client Specific Network~EB*G*IND*30***23*3000.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***23*250.00*****Y~MSG*Includes services provided by Client Specific Network~EB*C*FAM*30***23*15000.00*****N~EB*G*FAM*30***23*30000.00*****N~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*A*IND*30*****.10****Y~EB*C*IND*30***23*7500.00*****N~EB*G*IND*30***23*15000.00*****N~MSG*Deductible does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~EB*A*IND*30*****.50****N~EB*1**A7^BC^A8^A4^A5^A6^7^4^BB^22*********W~EB*C*IND*BC^A4^A6^4^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*22~EB*C*IND*A8****0.00****N*Y~MSG*Includes services provided by Client Specific Network~EB*C*IND*A4^A6^4^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*11~EB*C*IND*A4^A6^22****0.00****N*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*02~EB*B*IND*A4^A6^22***27*20.00****N*Y~III*ZZ*11~EB*A*IND*A4^A6^4^22*****.00***N*Y~III*ZZ*11~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Included For Specific Services~III*ZZ*02~EB*A*IND*A4^A6^22*****.00***N*Y~MSG*Included For Specific Services~III*ZZ*02~EB*A*IND*A4^A6^22*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*02~EB*A*IND*A4^A6^4^22*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*02~EB*B*IND*A4^A6^22***27*20.00****N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*A*IND*7*****.00***Y*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*11~EB*CB**7^BB********Y*Y~EB*C*IND*7****0.00****Y*Y~MSG*Includes services provided by Client Specific Network~III*ZZ*11~EB*A*IND*7*****.00***Y*Y~III*ZZ*11~EB*A*IND*4*****.00***N*Y~III*ZZ*22~EB*A*IND*4*****.00***N*Y~MSG*Services rendered thru Client Specific Network~III*ZZ*22~EB*C*IND*BB****0.00****Y*Y~MSG*Includes services provided by Client Specific Network~EB*1**MH~MSG* Provider is out of network based on NPI ID provided in request.~EB*G*FAM*30***29*5760.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*FAM*30***29*500.00*****Y~MSG*Includes services provided by Client Specific Network~EB*G*IND*30***29*2760.00*****Y~MSG*Includes services provided by Client Specific Network~MSG*Copay does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***29*250.00*****Y~MSG*Includes services provided by Client Specific Network~EB*C*FAM*30***29*15000.00*****N~EB*G*FAM*30***29*30000.00*****N~MSG*Coinsurance does apply to member's out-of-pocket maximum~MSG*Deductible does apply to member's out-of-pocket maximum~EB*C*IND*30***29*7500.00*****N~EB*G*IND*30***29*15000.00*****N~MSG*Deductible does apply to member's out-of-pocket maximum~MSG*Coinsurance does apply to member's out-of-pocket maximum~SE*119*1001~GE*1*1~IEA*1*123456782~]]>
Success
```
The response body includes the following elements:
| Element | Description |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PayloadType` | The type of the payload returned in the response.- `X12_271_Response_005010X279A1` for requests that pass X12 EDI validation. A 271 can contain benefits information for the patient or [`AAA` errors](/healthcare/eligibility-troubleshooting#payer-aaa-errors).
- `X12_999_Response_005010X231A1` for requests that fail [X12 EDI validation](/healthcare/eligibility-troubleshooting#x12-edi-validation-errors).
- `CoreEnvelopeError` when there's a [Core-compliant error](/healthcare/eligibility-troubleshooting#core-compliant-errors) or Stedi couldn't parse the X12 EDI envelope.
|
| `ProcessingMode` | The processing mode used for the request. This is always `RealTime`. |
| `PayloadID` | A unique identifier Stedi generated for the transaction. This won't be the same value you submitted as the `PayloadID` in the request. |
| `TimeStamp` | The timestamp when the response was generated in ISO 8601 format. |
| `SenderID` | The ID of the sender of the response. This is always the same as the `ReceiverID` in the request. |
| `ReceiverID` | The ID of the receiver of the response. This is always the same as the `SenderID` in the request. |
| `CORERuleVersion` | The CAQH CORE rule version. This is always `2.2.0`. |
| `Payload` | The X12 EDI response.- 271 Eligibility Benefit Response for requests that pass X12 EDI validation. A 271 can contain benefits information for the patient or [`AAA` errors](/healthcare/eligibility-troubleshooting#payer-aaa-errors).
- 999 Implementation Acknowledgment when the request fails [X12 EDI validation](/healthcare/eligibility-troubleshooting#x12-edi-validation-errors).
- Empty when the request fails due to a [CORE-compliant error](/healthcare/eligibility-troubleshooting#core-compliant-errors) or because Stedi couldn't parse the X12 EDI envelope.
|
| `ErrorCode` | The error code, if any, associated with the response. These errors typically indicate issues with the request body, such as missing or invalid elements. They can also indicate authentication issues and other processing errors. [Learn more](/healthcare/eligibility-troubleshooting#core-compliant-errors). |
| `ErrorMessage` | A description of the error, if any. |
| `Fault` | Only included when there is a [SOAP fault](/healthcare/eligibility-troubleshooting#soap-faults). It includes a `Code` and `Reason` element that describe the error. |
## HTTP status codes
| Status Code | Description |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200 OK` | Indicates a successful request. Note that Stedi returns a `200` even when the payer returns [`AAA` errors](/healthcare/eligibility-troubleshooting#payer-aaa-errors) in the 271 response. |
| `400 Bad Request` | Indicates a [SOAP fault](/healthcare/eligibility-troubleshooting#soap-faults), an error with the [SOAP request body](/healthcare/eligibility-troubleshooting#core-compliant-errors), or an [X12 EDI validation error](/healthcare/eligibility-troubleshooting#x12-edi-validation-errors). |
| `401 Unauthorized` | Indicates issues with the API key you provided. |
| `404 Not Found` | Indicates an error with the endpoint URL you provided. |
# Real-Time Eligibility Check JSON
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-eligibility
***
openapi: healthcare post /change/medicalnetwork/eligibility/v3
title: Real-Time Eligibility Check JSON
---------------------------------------
Real-time eligibility checks are ideal for in-person patient visits, telehealth appointments, and other scenarios where you need immediate information about a patient’s coverage.
1. Call this endpoint with a JSON payload. The required information can vary depending on the circumstances, but we recommend starting with a [basic eligibility request](/healthcare/send-eligibility-checks#body---json).
2. Stedi translates your request to the X12 270 EDI format and sends it to the payer.
3. The endpoint returns a synchronous response from the payer in both JSON and raw X12 EDI format. The response contains the patient's eligibility and benefits information. Note that our documentation lists all enums officially allowed in the eligibility response. Some payers return non-compliant values, which Stedi passes through as is.
Visit [Real-time eligibility checks](/healthcare/send-eligibility-checks) for a full how-to guide.
# Institutional Claims (837I) Raw X12
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-institutional-claims-raw-x12
***
openapi: healthcare post /change/medicalnetwork/institutionalclaims/v1/raw-x12-submission
title: Institutional Claims (837I) Raw X12
sidebarTitle: Institutional Claims Raw X12
***
This endpoint is ideal if you have an existing system that generates X12 EDI files and you want to send them through Stedi.
1. Call this endpoint with a payload in [837 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-institutional-x223a2/01JBHW2YXMN2F9KXK2PS0BFP9F).
2. Stedi validates the EDI and sends the claim to the payer.
3. The endpoint returns a response from Stedi in JSON format containing information about the claim you submitted and whether the submission was successful.
Visit [Submit institutional claims](/healthcare/submit-institutional-claims) for a full how-to guide.
# Institutional Claims JSON
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-institutional-claims
***
openapi: healthcare post /change/medicalnetwork/institutionalclaims/v1/submission
title: Institutional Claims JSON
--------------------------------
This endpoint sends 837I institutional claims to payers.
1. Call this endpoint with a JSON payload.
2. Stedi translates your request to the X12 837 EDI format and sends it to the payer.
3. The endpoint returns a response from Stedi in JSON format containing information about the claim you submitted and whether the submission was successful.
Visit [Submit institutional claims](/healthcare/submit-institutional-claims) for a full how-to guide.
# Submit Claim Attachment Raw X12
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-submit-claim-attachment-raw-x12
***
openapi: claims post /claim-attachments/raw-x12-submission
title: Submit Claim Attachment Raw X12
--------------------------------------
This endpoint is in **beta** and is subject to change.
This endpoint is ideal if you have an existing system that generates X12 EDI files and you want to send them through Stedi's API.
1. Call this endpoint with a payload in [275 X12 EDI format](https://portal.stedi.com/app/guides/view/hipaa/patient-information-x210/01HQ4HZ8ZBY2CZGPCVVM8JTK22).
2. Stedi sends the attachment to the payer, so the payer can use it to adjudicate the referenced 837 professional, dental, or institutional claim.
3. The endpoint returns summary information about the attachment submission.
This endpoint only supports [unsolicited attachments](/healthcare/submit-claim-attachments#solicited-vs-unsolicited-attachments).
Visit [Claim attachments](/healthcare/submit-claim-attachments#x12-edi) for a full how-to guide.
## Size limit
The size limit for attachments submitted in a single request is 6MB. If you need to submit larger attachments, you must submit them through [Stedi SFTP](/healthcare/submit-claims-sftp-connection) or the [JSON endpoints](/api-reference/healthcare/post-healthcare-create-claim-attachment).
# Submit Claim Attachment JSON
Source: https://www.stedi.com/docs/api-reference/healthcare/post-healthcare-submit-claim-attachment
***
openapi: claims post /claim-attachments/submission
title: Submit Claim Attachment JSON
-----------------------------------
This endpoint is in **beta** and is subject to change.
This endpoint submits a 275 claim attachment to a payer.
1. Call this endpoint with the required information to [link the attachment](/healthcare/submit-claim-attachments#reference-attachments-in-a-claim) to the correct claim.
2. Stedi generates the X12 EDI 275 transaction and sends it to the payer.
3. The endpoint returns summary information about the submission.
This endpoint is for 837 claims submitted in JSON format. If your system already generates X12 EDI, you can send attachments through the [Submit Claim Attachment (275) Raw X12](/api-reference/healthcare/post-healthcare-submit-claim-attachment-raw-x12) endpoint instead.
This endpoint only supports [unsolicited attachments](/healthcare/submit-claim-attachments#solicited-vs-unsolicited-attachments).
Visit [Claim attachments](/healthcare/submit-claim-attachments#json) for a full how-to guide.
# Insurance Discovery Check
Source: https://www.stedi.com/docs/api-reference/healthcare/post-insurance-discovery
***
openapi: healthcare post /insurance-discovery/check/v1
title: Insurance Discovery Check
sidebarTitle: Insurance Discovery Check
---------------------------------------
Insurance discovery checks search for a patient's active coverage using only their demographic data.
1. Call this endpoint with as much [patient demographic information](/healthcare/insurance-discovery#required-patient-information) as possible.
2. Stedi searches for active coverage for the patient.
3. The endpoint returns an array of potential active coverages along with subscriber details and benefits information.
We recommend using insurance discovery checks as a backup when eligibility checks fail or aren't possible. Because of their limitations, you shouldn't rely on them as your primary method for verifying patient coverage.
Visit [Insurance discovery checks](/healthcare/insurance-discovery) for a full how-to guide.
# EDI settings
Source: https://www.stedi.com/docs/edi-platform/configure/global-settings
***
title: EDI settings
sidebarTitle: EDI settings
--------------------------
You can configure the following behavior from the [EDI Settings](https://portal.stedi.com/app/core/settings) page. These settings apply to every partnership in your Stedi account.
## Inbound AS2
You can enable Inbound AS2 if you need to receive files from trading partners using an [AS2 connection](/edi-platform/configure/trading-partners/connections/as2/as2-overview). This isn't necessary if you are only sending outbound files over AS2.
## Inbound processing concurrency
Inbound processing concurrency lets you configure the number of inbound files Stedi processes at once. The concurrency limit applies across all partnerships within your Stedi account.
The default inbound concurrency limit is 25 files. If you need to process more files at once, [contact us](https://www.stedi.com/contact), and we can increase the limit for your account.
## Remote SFTP/FTPS static IP address
Enabling a static IP address ensures that your [Remote SFTP/FTPS connections](/edi-platform/configure/trading-partners/connections/remote-ftp) always use the same source IP address when communicating with remote servers. You can share this IP address with partners who require this additional level of access control.
If your partners don’t require a static IP address, we recommend leaving this setting as disabled.
## Automatic data removal
This functionality is available for Enterprise accounts. [Contact us](https://www.stedi.com/contact) for details.
Artifacts refer to the transaction and file execution payloads from files Stedi has processed. They contain the actual input/output transaction data in EDI, JSON, or another format. Artifacts do not include the metadata about a transaction or file execution, such as whether it was processed successfully.
You may want Stedi to remove artifacts after a certain timeframe - for example, to comply with your company's PII/PHI retention policies. You can configure the artifact retention period in **Automatic data removal**.
Once you set a retention period, Stedi deletes artifacts after the retention window has passed. **This affects both existing and future data in your account.**
For example, if you set a retention period of 30 days and process a file today, Stedi will delete the artifact after 30 total days have elapsed. Stedi will also delete any artifact that was created more than 30 days prior. **Stedi deletes historical files outside the retention window immediately upon configuring the retention period.** In this example, Stedi would not delete an artifact that was processed less than 30 days prior.
You cannot recover deleted artifacts.
# Configuration overview
Source: https://www.stedi.com/docs/edi-platform/configure
***
title: Configuration overview
sidebarTitle: Configuration overview
------------------------------------
You need the following configuration for each new trading partner.

## Partnership
A [partnership](/edi-platform/configure/trading-partners/profiles-and-partnerships) defines the EDI relationship between you and your trading partner.
Inside your partnership, you'll define all of the configuration specific to exchanging files with your partner, including the connection protocol, transaction settings, whether to send automatic acknowledgments, and more.
## Connection
A [connection](/edi-platform/configure/trading-partners/connections) configures the protocol you'll use to exchange files with your partner. This can be SFTP/FTPS or AS2.
Stedi automatically processes inbound files your partner sends over the connection. When you call Stedi's API to generate an outbound EDI file, Stedi automatically delivers it to your partner through the connection you configure for the partnership.
## Transaction settings
You'll create a [transaction setting](/edi-platform/configure/trading-partners/transaction-settings) for each EDI transaction type you plan to send or receive.
Transaction settings tell Stedi which [guide](/edi-platform/guides) (EDI requirements) to use for the transaction type.
* For inbound transactions, Stedi uses the attached guide to validate and translate the EDI into JSON.
* For outbound transactions, Stedi uses the guide to validate the JSON payload you submit to the API and then generate a fully-formed EDI file.
## Webhooks
[Webhooks](/edi-platform/configure/webhooks) are one of the most important integration points with the Stedi platform. They allow you to automatically send events from Stedi to any external API.
You'll configure at least one webhook to send `transaction.processed.v2` events to your business system. Then, you can programatically retrieve the processed transaction data from Stedi.
# Glossary
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/glossary
***
title: Glossary
sidebarTitle: "Glossary"
------------------------
## Composite element
A single [element](#element) that contains multiple values of different types, similar to a struct or record. The [specification](#specification) will specify which fields make up a composite element. The values in a composite element are kept apart by a [delimiter](#delimiter). The delimiter to use is specified in the [interchange](#interchange) header. In the following example, values are delimited using a `:`.
```
PRV*LA***ORT:HS:Y~
```
## Delimiter
A delimiter is used in the [X12 EDI Format](#x12-edi-format) to mark the end of a [segment](#segment) or [element](#element). The end of a [segment](#segment) is [delimited](#delimiter) by a `~` and the end of an [element](#element) by a `*`. Here's an example of two segments, both with three elements.
```
SE*2*0000~
GE*1*987654321~
```
There are also delimiters for [repeated elements](#repeated-element) and [composite elements](#composite-element), but these aren't standardized. Instead, these delimiters are specified in the [interchange](#interchange).
## Element
An element is a data field within a [segment](#segment). In the [X12 EDI Format](#x12-edi-format), elements in a [segment](#segment) are delimited by a `*`. For example, here's a [segment](#segment) with several elements.
```
GS*SO*00*00*20210902*1200*987654321*X*008010~
```
The values an element may contain, are described in a [specification](#specification).
## EDI (Electronic Data Interchange)
EDI – Electronic Data Interchange – is an umbrella term for many different “standardized” frameworks for exchanging business-to-business transactions like invoices, insurance applications, train sheets, credit reports. It is often used synonymously with two of the most popular standards – [X12](#x12-edi-format), used primarily in North America, and [EDIFACT](#edifact-format), which is prevalent throughout Europe. Read more: [What makes EDI so hard?](https://www.stedi.com/blog/what-makes-edi-so-hard)
## EDIFACT format
A file format for encoding [EDI](#edi) data, standardized by United Nations/Electronic Data Interchange for Administration, Commerce and Transport (UN/EDIFACT).
## Functional group
Within an [EDI](#edi) file, a functional group is a set of [transaction sets](#transaction-set). Typically, all the [transaction sets](#transaction-set) within a functional group are intended for the same department within an organization.
The beginning of a functional group is marked by the [GS](https://edi.stedi.com/x12-008010/segment/GS) [segment](#segment) and the end is marked by the [GE](https://edi.stedi.com/x12-008010/segment/GE) [segment](#segment). A functional group must be part of an [interchange](#interchange).
## Interchange
Within an [EDI](#edi) file, an interchange is a set of [functional groups](#functional-group) which in turn contain [transaction sets](#transaction-set). Typically, the contents of an interchange is intended for a specific organization and the contents of a [functional group](#functional-group) is intended for a specific department within that organization.
The beginning of an interchange is marked by the [`ISA`](https://edi.stedi.com/x12-008010/segment/ISA) [segment](#segment) and the end is marked by the [IEA](https://edi.stedi.com/x12-008010/segment/IEA) [segment](#segment). Every EDI file must have at least one interchange and consequently, every EDI file starts with an [`ISA`](https://edi.stedi.com/x12-008010/segment/ISA) [segment](#segment) and ends with an [IEA](https://edi.stedi.com/x12-008010/segment/IEA) [segment](#segment). Read more: [Control numbers in X12 EDI](https://www.stedi.com/blog/control-numbers-in-x12-edi).
## Loop
A loop is a collection of [segments](#segment) that can appear multiple times in a [transaction set](#transaction-set). The [segments](#segment) in a loop typically have a semantic relationalship, for example, the segments [Party Identification](https://www.stedi.com/edi/x12/segment/N1), [Geographic Location](https://www.stedi.com/edi/x12/segment/N4), and [Communication Contact Information](https://www.stedi.com/edi/x12/segment/COM) together can tell you about a single [trading partner](#trading-partner) and a loop of those segments allows you to refer to multiple [trading partners](#trading-partner) in a [transaction set](#transaction-set).
In [X12 EDI Format](#x12-edi-format), there's no special [delimiter](#delimiter) for loops, nor is there a set of [segments](#segment) that mark the begin and end of the loop, like there is for [interchanges](#interchange), [functional groups](#functional-group), and [transaction sets](#transaction-set). Instead, the segments in the loop are just repeated.
```
N1*21*Stedi*ZZ*ID001~
N4*New York**US~
COM*16*stedi.com~
N1*21*Acme*ZZ*ID002~
N4*Miami**US~
COM*16*acmebread.co~
```
## Repeated element
A single [element](#element) that contains multiple values of the same type, similar to a homogeneous array. Not every [element](#element) can be repeated; the [specification](#specification) must indicate that it's okay to do so.
In [X12 EDI Format](#x12-edi-format), the values in a repeated element are kept apart by a [delimiter](#delimiter). The delimiter to use is specified in the [interchange](#interchange) header. In the following example, values are delimited using a `/`.
```
AAA*Y***NF/NR/TO~
```
## Repeated segment
Within an [EDI](#edi) file, some segments can occur multiple times in a row. The [specification](#specification) will tell when a segment can be repeated.
In [X12 EDI Format](#x12-edi-format), a repeated segment appears as, well, a segment that's repeated.
```
NTE**When a segment has need to repeat,~
NTE**How does one accomplish that feat?~
NTE**It's really no bother.~
NTE**One after the other.~
NTE**A solution that's simple and neat.~
```
## Segment
Within an [EDI](#edi) file, a segment is a set of [elements](#element), where the segment is like a record and the [elements](#element) are its fields. Each segment starts with a segment identifier that tells you which [elements](#element) will follow. The different types of segments and their elements are listed in the [specification](#specification).
In the [X12 EDI Format](#x12-edi-format), segments are [delimited](#delimiter) by a `~`. It's also common to add a new line character after the [delimiter](#delimiter), but that's for human readability only and has no semantic value.
## Specification
A specification describes the data schema of a [transaction set](#transaction-set). It lists the [loops](#loop) and [segments](#segment), the order in which they appear, and the [elements](#element) within the [segments](#segment). The specification gives you all the information you need to write or interpret an [EDI](#edi) document that conforms to that specification.
[X12](#x12) has published [many specifications](https://edi.stedi.com/). A [trading partner](#trading-partner) can use these specifications directly, or they can base their own specification on one of them. Find popular EDI specifications in [the Stedi Network](https://www.stedi.com/edi/network).
## Trading partner
Any business that sends or receives business transactions.
## Transaction set
A transaction set is a type of business document, for example a purchase order, or a booking cancellation. Each transaction set is based on a [specification](#specification) that describes what data the transaction set can and must contain. There is a [list of standardized transaction sets](https://edi.stedi.com/).
The standard transaction sets are designed to be widely applicable. A [trading partner](#trading-partner) can take a transaction set, base its own [specification](#specification) on it, and only accept the data it knows how to handle. Many of these [business-specific transaction sets are available on Stedi](https://www.stedi.com/edi/network).
## X12
An organization that develops and maintains the [X12 EDI](#x12-edi-format) standards.
## X12 EDI Format
A file format for encoding [EDI](#edi) data, standardized by [X12](#x12). It's text-based and makes use of [delimiters](#delimiter) to mark the [segments](#segment) and [elements](#element).
# What is EDI?
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/what-is-edi
***
title: What is EDI?
sidebarTitle: 'What is EDI?'
----------------------------
Electronic Data Interchange (EDI) is a structured way for businesses to send and receive documents electronically. It was created in the 70's as a replacement for paper documents. EDI is like a schema to cover all possible business transactions across most industries, but it existed before the Internet was invented. Today, most every large company uses it including Amazon, Walmart, and FedEx.
Prior to EDI, businesses used to exchange paper transactions and record those transactions into a hand-written book called a ledger, but modern businesses use one or many software applications, called business systems, to facilitate operations. There are many types of business systems, ranging from generic software suites like Oracle, SAP, and NetSuite to vertical-specific products that serve some particular industry, like purpose-built systems for healthcare, agriculture, or education.
When broken down to its simplest definition, EDI can be thought of as "getting data from one business system into another".
## Common Uses of EDI
There are more than 300 different EDI transaction types. The following table contains examples of common EDI transactions.
| | |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Logistics** | - [204](https://www.stedi.com/edi/x12/transaction-set/204) Request pickup of a shipment (load tender)
- [990](https://www.stedi.com/edi/x12/transaction-set/990) Accept or reject the shipment (response to a load tender)
- [214](https://www.stedi.com/edi/x12/transaction-set/214) Shipment status update
- [210](https://www.stedi.com/edi/x12/transaction-set/210) Invoicing details for a shipment
|
| **Warehousing** | - [940](https://www.stedi.com/edi/x12/transaction-set/940) Request shipping from a warehouse
- [945](https://www.stedi.com/edi/x12/transaction-set/945) Communicate fulfillment to a seller
- [944](https://www.stedi.com/edi/x12/transaction-set/944) Indicate receipt of a stock transfer shipment
- [943](https://www.stedi.com/edi/x12/transaction-set/943) Stock transfer shipment notification
|
| **Retail** | - [850](https://www.stedi.com/edi/x12/transaction-set/850) Send a purchase order to a retailer
- [855](https://www.stedi.com/edi/x12/transaction-set/855) Send a purchase order acknowledgment back to a retailer
- [856](https://www.stedi.com/edi/x12/transaction-set/856) Send a ship notice to a retailer
- [810](https://www.stedi.com/edi/x12/transaction-set/810) Send an invoice
|
| **Healthcare** | - [834](https://portal.stedi.com/app/guides/view/hipaa/benefit-enrollment-and-maintenance-x220a1/01GRYB6D6RAWSG8ATBD6GXM13C) Send benefits enrollments to an insurance provider
- [277](https://portal.stedi.com/app/guides/view/hipaa/claim-acknowledgement-x214/01HACJ4MNFWR3GV3BCVAMG04PK) Indicate the status of a healthcare claim
- [276](https://portal.stedi.com/app/guides/view/hipaa/claim-status-request-x212/01GRYB6A4XEJQ61Y2K2KT606E5) Request the status of a healthcare claim
- [278](https://portal.stedi.com/app/guides/view/hipaa/health-care-services-review-information-review-x217/01GRYB6BA03R4N4W2VZ7EY927T) Communicate patient health information
- [835](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-paymentadvice-x221a1/01GRYB6DS30MGXWBPFZCM3695E) Make a payment and/or send an Explanation of Benefits (EOB) remittance advice
|
## EDI Standards
A few technical standards have been created since the introduction of EDI including X12 in North America and EDIFACT which is prevalent throughout Europe. Standards bodies make changes over time and version releases with names like “Release 004010”. These standards do not exist to solve all of the problems of B2B transactions. Instead they exist to allow a trading partner to understand each of its trading partner's internal syntax and vocabulary.
Standards such as X12 and EDIFACT provide highly structured, opinionated alternatives intended to reduce the surface area of knowledge required to successfully integrate with trading partners. All documents conforming to a given standard follow that standard’s syntax, allowing an adoptee of the standard to work with just one syntax for all trading partners who have also adopted that syntax.
## How is EDI transmitted?
EDI can be transmitted using various protocols, but these are the most common ways to exchange files with your trading partners.
### SFTP/FTPS
SFTP (SSH File Transfer Protocol) and FTPS (File Transfer Protocol Secure) are both secure file transfer protocols used to transmit files between computers over a network.
* SFTP is a secure version of the FTP protocol, providing encryption and authentication using the Secure Shell (SSH) protocol. It encrypts both the data being transmitted and the commands used to perform file operations.
* FTPS is an extension of the FTP protocol that adds support for Transport Layer Security (TLS) or Secure Sockets Layer (SSL) encryption. It can use either implicit SSL, where the entire session is encrypted from the start, or explicit SSL, where the client requests a secure connection after connecting to the server.
You can set up your own SFTP/FTPS server for your trading partner to connect to, or (common with large trading partners) you will need to connect to your trading partner's remote SFTP/FTPS server to exchange files.
### AS2
AS2, or Applicability Statement 2, supports encryption of the data being exchanged and uses digital signatures to verify the authenticity and integrity of the data. AS2 also supports MDN (message disposition notification), a way for your partner to acknowledge that they have received your message. Some partners may require that you request and accept an MDN response, send MDN responses, or both.
### Value Added Network (VAN)
A VAN acts as an intermediary between trading partners. Instead of establishing a direct connection with your trading partners, you and your partners would connect to a VAN, and the VAN would broker the connection for you. It is not a requirement for you and your partners to use the same VAN — this is called a "VAN to VAN interconnect."
VANs often provide additional services on top of basic message routing. These may include data translation between different EDI standards, data encryption for security, data archiving, auditing, and tracking of transactions.
# Split inbound EDI files with fragments
Source: https://www.stedi.com/docs/edi-platform/fragments/inbound-fragments
***
title: "Split inbound EDI files with fragments"
sidebarTitle: "Inbound files"
-----------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
Once you [configure fragments](/edi-platform/fragments) for an inbound transaction setting, Stedi splits the translated transaction payload into chunks based on the selected segment.
## Processing events
Stedi emits two types of events for inbound transactions with fragments enabled: `transaction.processed.v2` and `fragment.processed.v2`.
For example, if you enable fragments on `Loop 2000` (Member Level Detail) in an 834 Healthcare Benefit Enrollment. Stedi will fragment a translated 834 file and emit the following events:
* One [`transaction.processed.v2` event](/edi-platform/operate/event-types#transaction-processed) for each unique transaction set that was included in the original file.
* One or more [`fragment.processed.v2` events](/edi-platform/operate/event-types#transaction-processed). Each fragment contains several iterations of `Loop 2000` (Member Level Detail), the start of which is indicated by the presence of the required initial `INS` segment.
## Ingest fragments
You have two options for ingesting fragments from processed inbound transactions into your downstream system.
### Fragment processed events
Configure a [webhook](/edi-platform/configure/webhooks/configure-webhooks) for fragment processed events. As Stedi emits these events, use the [Get Fragment](/api-reference/edi-platform/core/get-transaction-fragment-detail) endpoint to retrieve each processed fragment from Stedi.
### Transaction processed events
Configure a [webhook](/edi-platform/configure/webhooks/configure-webhooks) for transaction processed events only. After you receive a transaction processed event, use the API to retrieve associated fragments in batches according to your system's requirements.
The event payload includes a `fragments` object with general information about the fragments that Stedi created.
```json Translated inventory file with fragments
{
"event": {
"version": "0",
"id": "85634bf9-8359-4a9b-b8f3-66616d896f51",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2023-11-13T15:47:09Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/transactions/1b1d2424-72ba-4157-bcfa-3e1620430a3f"
],
"detail": {
"transactionId": "1b1d2424-72ba-4157-bcfa-3e1620430a3f",
"direction": "INBOUND",
"mode": "production",
"fileExecutionId": "bb141a6f-79f8-9c88-9b91-37609ddd90f9",
"processedAt": "2023-11-13T15:47:09.231Z",
"fragments": {
"batchSize": 800,
"fragmentCount": 1,
"keyName": "member_level_detail_INS_loop"
},
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"url": "https://core.us.stedi.com/2023-08-01/transactions/1b1d2424-72ba-4157-bcfa-3e1620430a3f/input",
"sizeBytes": 665,
"model": "transaction"
},
{
"artifactType": "application/json",
"usage": "output",
"url": "https://core.us.stedi.com/2023-08-01/transactions/1b1d2424-72ba-4157-bcfa-3e1620430a3f/output",
"sizeBytes": 825,
"model": "transaction"
}
],
"partnership": {
"partnershipId": "sender_receiver",
"partnershipType": "x12",
"sender": { "profileId": "sender" },
"receiver": { "profileId": "receiver" }
},
"x12": {
"transactionSetting": {
"guideId": "01H9JMMG4839VQG9QQVSZ6X29G",
"transactionSettingId": "01HF4N77F5YWA2RXEDMMF5FF6J"
},
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "0",
"controlNumber": 76
},
"functionalGroup": {
"controlNumber": 76,
"release": "004010",
"date": "2022-09-24",
"time": "20:01",
"functionalIdentifierCode": "IB"
},
"transaction": {
"controlNumber": "319101",
"transactionSetIdentifier": "834"
},
"receiver": {
"applicationCode": "RECEIVER",
"isa": { "qualifier": "ZZ", "id": "RECEIVER" }
},
"sender": {
"applicationCode": "SENDER",
"isa": { "qualifier": "ZZ", "id": "SENDER" }
}
}
},
"connectionId": "01H1CH2ZES1Z8AW94A3RQSRWRW" // optional
}
}
}
```
## Retrieve inbound transaction with fragments
Stedi does not store the complete transaction for inbound files with fragments enabled. When you use Stedi's [Get Transaction](/api-reference/edi-platform/core/get-transactions) endpoint to retrieve inbound transactions with fragments, Stedi always returns the fragment wrapper (the transaction minus fragments).
You cannot retrieve the complete transaction with fragments included - you must use the [Get Fragment](/api-reference/edi-platform/core/get-transaction-fragment-detail) endpoint to retrieve the fragments separately.
# Fragments: Split transactions into smaller chunks
Source: https://www.stedi.com/docs/edi-platform/fragments
***
title: 'Fragments: Split transactions into smaller chunks'
sidebarTitle: 'Configure'
-------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
Large files are often the result of transaction sets containing many repeated loops or segments. For example, a healthcare provider may send an [837 Health Care Claim](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-professional-x222a2/01GRYB6EJ999Y6MZ53ZBAHYBHE) containing many individual claims, or a brand may send an [846 Inventory Inquiry/Advice](https://www.stedi.com/edi/x12/transaction-set/846) file containing millions of SKUs.
The translation ratio of an EDI file to JSON typically approaches 1:10, so a translated JSON artifact will be multiple times the size of the original EDI file. To avoid overwhelming downstream systems, you can use fragments to split translated inbound transactions from Stedi into smaller, more manageable chunks.
You can also use fragments when generating large outbound EDI files. You send transaction data to Stedi in chunks over time, and Stedi stiches the chunks together to generate a complete EDI file for your trading partner.
## Configure fragments
You need to configure your Stedi guide to use fragments and then create an inbound or outbound transaction setting using that guide.
### Stedi guide
You can enable fragments for one repeated EDI segment in each transaction set. To enable fragments within a Stedi guide:
1. Go to the [Guides](https://portal.stedi.com/app/guides) page and edit the guide you want to update.
2. Click the node (segment) in the guide that you want to use to split the file. The node must be a looping data structure, such as an HL loop containing inventory items.
3. Toggle **Set as fragment** to `ON`.
4. Publish the changes to your guide.
### Transaction setting
Once you have enabled fragments on the Stedi guide, create a [transaction setting](/edi-platform/configure/trading-partners/transaction-settings#create-transaction-settings) with the guide.
* **Inbound transaction settings**: You must explicitly toggle **Enable fragments** to `ON`. You can use the default batch size (800 segments) or set a custom batch size (up to 50,000 segments).
* **Outbound transaction settings**: No additional configuration is required.
You can now use fragments to split large [inbound transactions](/edi-platform/fragments/inbound-fragments) or generate large [outbound transactions](/edi-platform/fragments/outbound-fragments).
# Generate outbound EDI files with fragments
Source: https://www.stedi.com/docs/edi-platform/fragments/outbound-fragments
***
title: "Generate outbound EDI files with fragments"
sidebarTitle: "Outbound files"
------------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
Once you [configure fragments](/edi-platform/fragments) for a transaction type, you can use Stedi's APIs to generate EDI files from fragments.
For example, if you enable fragments on the `INS` loop in an 834 Health Care Benefit Enrollment and Maintenance, you can send batches of `INS` loops to Stedi's [Stage Fragment API](/api-reference/edi-platform/core/post-fragments), and Stedi will securely store them until you're ready to send the complete file.
Once you stage all the fragments, you call the [Create Outbound Transaction API](/api-reference/edi-platform/post-transactions) to combine the fragments together into a single EDI file and deliver it to your trading partner.
## Find the Guide JSON Schema
Unless you're using [mappings](/edi-platform/mappings), you must send fragments in [Guide JSON](/edi-platform/operate/transform-json/guide-json), a JSON format that matches the JSON Schema of the guide associated with the outbound transaction setting.
To find the JSON Schema for a fragment:
1. Navigate to the [Trading partners page](https://portal.stedi.com/app/core/partnerships).
2. Select the partnership.
3. Click the name of the guide associated with the outbound transaction setting.
4. Open the **Actions** menu and select **View schema**.
5. Find the segment that you selected to split the file. The shape for that segment is the JSON Schema you must use when sending fragments to Stedi.
The following example shows the JSON Schema for `Loop 2000` (Member Level Detail) in an 834 Healthcare Benefit Enrollment and Maintenance transaction. The start of this loop is the `INS` segment, which is where Stedi will split the file.
```json tab="JSON example"
{
"member_level_detail_INS_loop": [
{
"member_level_detail_INS": {
"member_indicator_01": "Y",
"individual_relationship_code_02": "18",
"maintenance_type_code_03": "021",
"maintenance_reason_code_04": "20",
"benefit_status_code_05": "A",
"employment_status_code_08": "FT"
},
"subscriber_identifier_REF": {
"reference_identification_qualifier_01": "0F",
"subscriber_identifier_02": "123456789"
},
"member_policy_number_REF": {
"reference_identification_qualifier_01": "1L",
"member_group_or_policy_number_02": "123456001"
},
"member_level_dates_DTP": [
{
"date_time_qualifier_01": "356",
"date_time_period_format_qualifier_02": "D8",
"status_information_effective_date_03": "19960523"
}
],
"member_name_NM1_loop": {
"member_name_NM1": {
"entity_identifier_code_01": "IL",
"entity_type_qualifier_02": "1",
"member_last_name_03": "DOE",
"member_first_name_04": "JOHN",
"member_middle_name_05": "P",
"identification_code_qualifier_08": "34",
"member_identifier_09": "123456789"
},
"member_communications_numbers_PER": {
"contact_function_code_01": "IP",
"communication_number_qualifier_03": "HP",
"communication_number_04": "7172343334",
"communication_number_qualifier_05": "WP",
"communication_number_06": "7172341240"
},
"member_residence_street_address_N3": {
"member_address_line_01": "100 MARKET ST",
"member_address_line_02": "APT 3G"
},
"member_city_state_zip_code_N4": {
"member_city_name_01": "CAMP HILL",
"member_state_code_02": "PA",
"member_postal_zone_or_zip_code_03": "17011",
"location_qualifier_05": "CY",
"location_identifier_06": "CUMBERLAND"
},
"member_demographics_DMG": {
"date_time_period_format_qualifier_01": "D8",
"member_birth_date_02": "19400816",
"gender_code_03": "M"
}
},
"health_coverage_HD_loop": [
{
"health_coverage_HD": {
"maintenance_type_code_01": "021",
"insurance_line_code_03": "HLT"
},
"health_coverage_dates_DTP": [
{
"date_time_qualifier_01": "348",
"date_time_period_format_qualifier_02": "D8",
"coverage_period_03": "19960601"
}
],
"coordination_of_benefits_COB_loop": [
{
"coordination_of_benefits_COB": {
"payer_responsibility_sequence_number_code_01": "P",
"member_group_or_policy_number_02": "890111",
"coordination_of_benefits_code_03": "5"
}
}
]
},
{
"health_coverage_HD": {
"maintenance_type_code_01": "021",
"insurance_line_code_03": "DEN"
},
"health_coverage_dates_DTP": [
{
"date_time_qualifier_01": "348",
"date_time_period_format_qualifier_02": "D8",
"coverage_period_03": "19960601"
}
]
},
{
"health_coverage_HD": {
"maintenance_type_code_01": "021",
"insurance_line_code_03": "VIS"
},
"health_coverage_dates_DTP": [
{
"date_time_qualifier_01": "348",
"date_time_period_format_qualifier_02": "D8",
"coverage_period_03": "19960601"
}
]
}
]
}
]
}
```
```json tab="JSON Schema"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"member_level_detail_INS_loop": {
"items": {
"additionalProperties": false,
"properties": {
"member_level_detail_INS": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P1112",
"type": "object",
"dependentRequired": {
"date_time_period_format_qualifier_11": [
"member_individual_death_date_12"
],
"member_individual_death_date_12": [
"date_time_period_format_qualifier_11"
]
}
}
],
"description": "To provide benefit information on insured entities",
"properties": {
"member_indicator_01": {
"description": "Code indicating a Yes or No condition or response\n\n- INS01 indicates status of the insured. A \"Y\" value indicates the insured is a subscriber: an \"N\" value indicates the insured is a dependent.",
"enum": ["N", "Y"],
"title": "Member Indicator",
"type": "string",
"x12-codes": {
"N": {
"description": "No",
"code": "N"
},
"Y": {
"description": "Yes",
"code": "Y"
}
}
},
"individual_relationship_code_02": {
"description": "Code indicating the relationship between two individuals or entities",
"enum": [
"01",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"23",
"24",
"25",
"26",
"31",
"38",
"53",
"60",
"D2",
"G8",
"G9"
],
"title": "Individual Relationship Code",
"type": "string",
"x12-codes": {
"10": {
"description": "Foster Child",
"code": "10"
},
"11": {
"description": "Son-in-law or Daughter-in-law",
"code": "11"
},
"12": {
"description": "Brother-in-law or Sister-in-law",
"code": "12"
},
"13": {
"description": "Mother-in-law or Father-in-law",
"code": "13"
},
"14": {
"description": "Brother or Sister",
"code": "14"
},
"15": {
"description": "Ward",
"code": "15"
},
"16": {
"description": "Stepparent",
"code": "16"
},
"17": {
"description": "Stepson or Stepdaughter",
"code": "17"
},
"18": {
"description": "Self",
"code": "18"
},
"19": {
"description": "Child",
"code": "19"
},
"23": {
"description": "Sponsored Dependent",
"code": "23",
"x12-usage-notes": "Dependents between the ages of 19 and 25 not attending school; age qualifications may vary depending on policy."
},
"24": {
"description": "Dependent of a Minor Dependent",
"code": "24"
},
"25": {
"description": "Ex-spouse",
"code": "25"
},
"26": {
"description": "Guardian",
"code": "26"
},
"31": {
"description": "Court Appointed Guardian",
"code": "31"
},
"38": {
"description": "Collateral Dependent",
"code": "38",
"x12-usage-notes": "Relative related by blood or marriage who resides in the home and is dependent on the insured for a major portion of their support."
},
"53": {
"description": "Life Partner",
"code": "53",
"x12-usage-notes": "This is a partner that acts like a spouse without a legal marriage committment."
},
"60": {
"description": "Annuitant",
"code": "60"
},
"01": {
"description": "Spouse",
"code": "01"
},
"03": {
"description": "Father or Mother",
"code": "03"
},
"04": {
"description": "Grandfather or Grandmother",
"code": "04"
},
"05": {
"description": "Grandson or Granddaughter",
"code": "05"
},
"06": {
"description": "Uncle or Aunt",
"code": "06"
},
"07": {
"description": "Nephew or Niece",
"code": "07"
},
"08": {
"description": "Cousin",
"code": "08"
},
"09": {
"description": "Adopted Child",
"code": "09"
},
"D2": {
"description": "Trustee",
"code": "D2"
},
"G8": {
"description": "Other Relationship",
"code": "G8"
},
"G9": {
"description": "Other Relative",
"code": "G9"
}
},
"x12-usage-notes": "- The value 18 must be used for the subscriber.;\n- For dependents, this value identifies their relationship to the subscriber. For example, a daughter would be value 19."
},
"maintenance_type_code_03": {
"description": "Code identifying the specific type of item maintenance",
"enum": ["001", "021", "024", "025", "030"],
"title": "Maintenance Type Code",
"type": "string",
"x12-codes": {
"001": {
"description": "Change",
"code": "001",
"x12-usage-notes": "Use this code to indicate a change to an existing subscriber/dependent record."
},
"021": {
"description": "Addition",
"code": "021",
"x12-usage-notes": "Use this code to add a subscriber or dependent."
},
"024": {
"description": "Cancellation or Termination",
"code": "024",
"x12-usage-notes": "Use this code for cancellation, termination, or deletion of a subscriber or dependent."
},
"025": {
"description": "Reinstatement",
"code": "025",
"x12-usage-notes": "Use this code for reinstatement of a cancelled subscriber/dependent record."
},
"030": {
"description": "Audit or Compare",
"code": "030",
"x12-usage-notes": "Use this code when sending a full file (BGN08 = `4' or `RX') to verify that the sponsor and payer databases are synchronized. See section 1.4.5, Update, Versus Full File Audits, Versus Full File Replacements, for additional information."
}
}
},
"maintenance_reason_code_04": {
"description": "Code identifying the reason for the maintenance change",
"enum": [
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"14",
"15",
"16",
"17",
"18",
"20",
"21",
"22",
"25",
"26",
"27",
"28",
"29",
"31",
"32",
"33",
"37",
"38",
"39",
"40",
"41",
"43",
"59",
"AA",
"AB",
"AC",
"AD",
"AE",
"AF",
"AG",
"AH",
"AI",
"AJ",
"AL",
"EC",
"XN",
"XT"
],
"title": "Maintenance Reason Code",
"type": "string",
"x12-codes": {
"10": {
"description": "Consolidation Omnibus Budget Reconciliation Act (COBRA) Premium Paid",
"code": "10"
},
"11": {
"description": "Surviving Spouse",
"code": "11"
},
"14": {
"description": "Voluntary Withdrawal",
"code": "14"
},
"15": {
"description": "Primary Care Provider (PCP) Change",
"code": "15"
},
"16": {
"description": "Quit",
"code": "16"
},
"17": {
"description": "Fired",
"code": "17"
},
"18": {
"description": "Suspended",
"code": "18"
},
"20": {
"description": "Active",
"code": "20"
},
"21": {
"description": "Disability",
"code": "21"
},
"22": {
"description": "Plan Change",
"code": "22",
"x12-usage-notes": "Use this code when a member changes from one Plan to a different Plan. This is not intended to identify changes to a Plan."
},
"25": {
"description": "Change in Identifying Data Elements",
"code": "25",
"x12-usage-notes": "Use this code when a change has been made to the primary elements that identify a member. Such primary elements include the following: first name, last name, Social Security Number, date of birth, and employee identification number."
},
"26": {
"description": "Declined Coverage",
"code": "26",
"x12-usage-notes": "Use this code when a member declined a previously active coverage."
},
"27": {
"description": "Pre-Enrollment",
"code": "27",
"x12-usage-notes": "Use this code to enroll newborns prior to receiving the newborn's application."
},
"28": {
"description": "Initial Enrollment",
"code": "28",
"x12-usage-notes": "Use this code the first time the member selected coverage with the Plan Sponsor."
},
"29": {
"description": "Benefit Selection",
"code": "29",
"x12-usage-notes": "Use this code when a member changes benefits within a Plan."
},
"31": {
"description": "Legal Separation",
"code": "31"
},
"32": {
"description": "Marriage",
"code": "32"
},
"33": {
"description": "Personnel Data",
"code": "33",
"x12-usage-notes": "Use this code for any data change that is not included in any of the other allowed codes. An example would be change in Coordination of Benefits information."
},
"37": {
"description": "Leave of Absence with Benefits",
"code": "37"
},
"38": {
"description": "Leave of Absence without Benefits",
"code": "38"
},
"39": {
"description": "Lay Off with Benefits",
"code": "39"
},
"40": {
"description": "Lay Off without Benefits",
"code": "40"
},
"41": {
"description": "Re-enrollment",
"code": "41"
},
"43": {
"description": "Change of Location",
"code": "43",
"x12-usage-notes": "Use this code to indicate a change of address."
},
"59": {
"description": "Non Payment",
"code": "59"
},
"01": {
"description": "Divorce",
"code": "01"
},
"02": {
"description": "Birth",
"code": "02"
},
"03": {
"description": "Death",
"code": "03"
},
"04": {
"description": "Retirement",
"code": "04"
},
"05": {
"description": "Adoption",
"code": "05"
},
"06": {
"description": "Strike",
"code": "06"
},
"07": {
"description": "Termination of Benefits",
"code": "07"
},
"08": {
"description": "Termination of Employment",
"code": "08"
},
"09": {
"description": "Consolidation Omnibus Budget Reconciliation Act (COBRA)",
"code": "09"
},
"AA": {
"description": "Dissatisfaction with Office Staff",
"code": "AA"
},
"AB": {
"description": "Dissatisfaction with Medical Care/Services Rendered",
"code": "AB"
},
"AC": {
"description": "Inconvenient Office Location",
"code": "AC"
},
"AD": {
"description": "Dissatisfaction with Office Hours",
"code": "AD"
},
"AE": {
"description": "Unable to Schedule Appointments in a Timely Manner",
"code": "AE"
},
"AF": {
"description": "Dissatisfaction with Physician's Referral Policy",
"code": "AF"
},
"AG": {
"description": "Less Respect and Attention Time Given than to Other Patients",
"code": "AG"
},
"AH": {
"description": "Patient Moved to a New Location",
"code": "AH"
},
"AI": {
"description": "No Reason Given",
"code": "AI"
},
"AJ": {
"description": "Appointment Times not Met in a Timely Manner",
"code": "AJ"
},
"AL": {
"description": "Algorithm Assigned Benefit Selection",
"code": "AL"
},
"EC": {
"description": "Member Benefit Selection",
"code": "EC",
"x12-usage-notes": "Use this code for initial and subsequent enrollment when an insurance carrier needs to recognize that a member made an explicit plan choice."
},
"XN": {
"description": "Notification Only",
"code": "XN",
"x12-usage-notes": "Use this code in complete enrollment transmissions. This is used when INS03 is equal to 030 (Audit/Compare)."
},
"XT": {
"description": "Transfer",
"code": "XT",
"x12-usage-notes": "Use this code when a member has an organizational change (i.e. a location change within the organization) with no change in benefits or plan."
}
}
},
"benefit_status_code_05": {
"description": "The type of coverage under which benefits are paid",
"enum": ["A", "C", "S", "T"],
"title": "Benefit Status Code",
"type": "string",
"x12-codes": {
"A": {
"description": "Active",
"code": "A"
},
"C": {
"description": "Consolidated Omnibus Budget Reconciliation Act (COBRA)",
"code": "C"
},
"S": {
"description": "Surviving Insured",
"code": "S"
},
"T": {
"description": "Tax Equity and Fiscal Responsibility Act (TEFRA)",
"code": "T"
}
}
},
"medicare_status_code_06": {
"description": "To provide Medicare coverage and associated reason for Medicare eligibility",
"properties": {
"medicare_plan_code_01": {
"description": "Code identifying the Medicare Plan",
"enum": ["A", "B", "C", "D", "E"],
"title": "Medicare Plan Code",
"type": "string",
"x12-codes": {
"A": {
"description": "Medicare Part A",
"code": "A"
},
"B": {
"description": "Medicare Part B",
"code": "B"
},
"C": {
"description": "Medicare Part A and B",
"code": "C"
},
"D": {
"description": "Medicare",
"code": "D"
},
"E": {
"description": "No Medicare",
"code": "E"
}
}
},
"medicare_eligibility_reason_code_02": {
"description": "Code specifying reason for eligibility",
"enum": ["0", "1", "2"],
"title": "Medicare Eligibility Reason Code",
"type": "string",
"x12-codes": {
"0": {
"description": "Age",
"code": "0"
},
"1": {
"description": "Disability",
"code": "1"
},
"2": {
"description": "End Stage Renal Disease (ESRD)",
"code": "2"
}
}
}
},
"required": ["medicare_plan_code_01"],
"title": "Medicare Status Code",
"type": "object",
"x12-usage-notes": "Required if a member is being enrolled or disenrolled in Medicare, is currently in Medicare or has terminated or changed their Medicare enrollment. If not required by this implementation guide, do not send."
},
"consolidated_omnibus_budget_reconciliation_act_cobra_qualifying_event_code_07": {
"description": "A Qualifying Event is any of the following which results in loss of coverage for a Qualified Beneficiary",
"enum": [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"ZZ"
],
"title": "Consolidated Omnibus Budget Reconciliation Act (COBRA) Qualifying Event Code",
"type": "string",
"x12-codes": {
"1": {
"description": "Termination of Employment",
"code": "1"
},
"2": {
"description": "Reduction of work hours",
"code": "2"
},
"3": {
"description": "Medicare",
"code": "3"
},
"4": {
"description": "Death",
"code": "4"
},
"5": {
"description": "Divorce",
"code": "5"
},
"6": {
"description": "Separation",
"code": "6"
},
"7": {
"description": "Ineligible Child",
"code": "7"
},
"8": {
"description": "Bankruptcy of Retiree's Former Employer (26 U.S.C. 4980B(f)(3)(F))",
"code": "8"
},
"9": {
"description": "Layoff",
"code": "9"
},
"10": {
"description": "Leave of Absence",
"code": "10"
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ"
}
}
},
"employment_status_code_08": {
"description": "Code showing the general employment status of an employee/claimant",
"enum": ["AC", "AO", "AU", "FT", "L1", "PT", "RT", "TE"],
"title": "Employment Status Code",
"type": "string",
"x12-codes": {
"AC": {
"description": "Active",
"code": "AC"
},
"AO": {
"description": "Active Military - Overseas",
"code": "AO"
},
"AU": {
"description": "Active Military - USA",
"code": "AU"
},
"FT": {
"description": "Full-time",
"code": "FT",
"x12-usage-notes": "Full time active employee"
},
"L1": {
"description": "Leave of Absence",
"code": "L1"
},
"PT": {
"description": "Part-time",
"code": "PT",
"x12-usage-notes": "Part time Active Employee"
},
"RT": {
"description": "Retired",
"code": "RT"
},
"TE": {
"description": "Terminated",
"code": "TE"
}
},
"x12-usage-notes": "- If this insurance enrollment is through a non-employment based program such as Medicare or Medicaid then this data element will contain the status of the subscriber in that program, rather than their employment status. Codes for non-employment based programs will be limited to \"AC\", Active and \"TE\", Terminated."
},
"student_status_code_09": {
"description": "Code indicating the student status of the patient if 19 years of age or older, not handicapped and not the insured",
"enum": ["F", "N", "P"],
"title": "Student Status Code",
"type": "string",
"x12-codes": {
"F": {
"description": "Full-time",
"code": "F"
},
"N": {
"description": "Not a Student",
"code": "N"
},
"P": {
"description": "Part-time",
"code": "P"
}
}
},
"handicap_indicator_10": {
"description": "Code indicating a Yes or No condition or response\n\n- INS10 is the handicapped status indicator. A \"Y\" value indicates an individual is handicapped; an \"N\" value indicates an individual is not handicapped.",
"enum": ["N", "Y"],
"title": "Handicap Indicator",
"type": "string",
"x12-codes": {
"N": {
"description": "No",
"code": "N"
},
"Y": {
"description": "Yes",
"code": "Y"
}
}
},
"date_time_period_format_qualifier_11": {
"description": "Code indicating the date format, time format, or date and time format",
"enum": ["D8"],
"title": "Date Time Period Format Qualifier",
"type": "string",
"x12-codes": {
"D8": {
"description": "Date Expressed in Format CCYYMMDD",
"code": "D8"
}
}
},
"member_individual_death_date_12": {
"description": "Expression of a date, a time, or range of dates, times or dates and times\n\n- INS12 is the date of death.",
"maxLength": 35,
"minLength": 1,
"title": "Member Individual Death Date",
"type": "string"
},
"confidentiality_code_13": {
"description": "Code indicating the access to insured information",
"enum": ["R", "U"],
"title": "Confidentiality Code",
"type": "string",
"x12-codes": {
"R": {
"description": "Restricted Access",
"code": "R"
},
"U": {
"description": "Unrestricted Access",
"code": "U"
}
}
},
"birth_sequence_number_17": {
"description": "A generic number\n\n- INS17 is the number assigned to each family member born with the same birth date. This number identifies birth sequence for multiple births allowing proper tracking and response of benefits for each dependent (i.e., twins, triplets, etc.).",
"title": "Birth Sequence Number",
"type": "integer",
"x12-max-length": 9,
"minimum": -999999999,
"maximum": 999999999
}
},
"required": [
"member_indicator_01",
"individual_relationship_code_02",
"maintenance_type_code_03",
"benefit_status_code_05"
],
"title": "Member Level Detail",
"type": "object",
"x12-usage-notes": "- Subscriber information must preceed dependent information in a transmission, or the subscriber information must have been submitted to the receiver in a previous transmission."
},
"member_policy_number_REF": {
"additionalProperties": false,
"description": "To specify identifying information",
"properties": {
"reference_identification_qualifier_01": {
"description": "Code qualifying the Reference Identification",
"enum": ["1L"],
"title": "Reference Identification Qualifier",
"type": "string",
"x12-codes": {
"1L": {
"description": "Group or Policy Number",
"code": "1L",
"x12-usage-notes": "The submitter sends the payer's pre-assigned Group or Policy Number."
}
}
},
"member_group_or_policy_number_02": {
"description": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier",
"maxLength": 50,
"minLength": 1,
"title": "Member Group or Policy Number",
"type": "string"
}
},
"required": [
"reference_identification_qualifier_01",
"member_group_or_policy_number_02"
],
"title": "Member Policy Number",
"type": "object",
"x12-usage-notes": "- The policy number passed in this segment is an attribute of the contract relationship between the plan sponsor (sender) and the payer (receiver) and not an attribute of an individual's participation in any coverage passed in an HD loop.\n- Required when the policy or group number applies to all coverage data (all 2300 loops for this member). If not required by this implementation guide, do not send."
},
"member_supplemental_identifier_REF": {
"items": {
"additionalProperties": false,
"description": "To specify identifying information",
"properties": {
"reference_identification_qualifier_01": {
"description": "Code qualifying the Reference Identification",
"enum": [
"3H",
"4A",
"6O",
"17",
"23",
"ABB",
"D3",
"DX",
"F6",
"P5",
"Q4",
"QQ",
"ZZ"
],
"title": "Reference Identification Qualifier",
"type": "string",
"x12-codes": {
"17": {
"description": "Client Reporting Category",
"code": "17",
"x12-usage-notes": "Used when further identification of a member is required under the insurance contract between the sponsor and the payer and allowed by federal and state regulations."
},
"23": {
"description": "Client Number",
"code": "23",
"x12-usage-notes": "To be used to pass a payer specific identifier for a member. Not to be used after the HIPAA standard National Identifier for Individuals is implemented."
},
"3H": {
"description": "Case Number",
"code": "3H"
},
"4A": {
"description": "Personal Identification Number (PIN)",
"code": "4A",
"x12-usage-notes": "Use this code to transmit a password that is associated with the member's record."
},
"6O": {
"description": "Cross Reference Number",
"code": "6O",
"x12-usage-notes": "Used when further identification of a member is required for reporting, indexing, or other purpose as mutually agreed upon between the sender and receiver of the transaction set."
},
"ABB": {
"description": "Personal ID Number",
"code": "ABB"
},
"D3": {
"description": "National Council for Prescription Drug Programs Pharmacy Number",
"code": "D3"
},
"DX": {
"description": "Department/Agency Number",
"code": "DX",
"x12-usage-notes": "Use when members in a coverage group are set up as different departments or divisions under the terms of the insurance policy."
},
"F6": {
"description": "Health Insurance Claim (HIC) Number",
"code": "F6",
"x12-usage-notes": "Use when reporting Medicare eligibility for a member until the National Identifier is mandated for use."
},
"P5": {
"description": "Position Code",
"code": "P5",
"x12-usage-notes": "Use this code to transmit the title of the member's employment position."
},
"Q4": {
"description": "Prior Identifier Number",
"code": "Q4",
"x12-usage-notes": "Use to pass the Identifier Number under which the member had previous coverage with the payer. This could be the result of a change in employment or coverage that resulted in a new ID number being assigned but left the member covered by the same payer."
},
"QQ": {
"description": "Unit Number",
"code": "QQ",
"x12-usage-notes": "Use when members in a coverage group are set up as different units under the terms of the insurance policy. Units may exist within another grouping such as division or department."
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ"
}
}
},
"member_supplemental_identifier_02": {
"description": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier",
"maxLength": 50,
"minLength": 1,
"title": "Member Supplemental Identifier",
"type": "string"
}
},
"required": [
"reference_identification_qualifier_01",
"member_supplemental_identifier_02"
],
"title": "Member Supplemental Identifier",
"type": "object",
"x12-usage-notes": "- Required when sending additional identifying information on the member. If not required by this implementation guide, do not send."
},
"maxItems": 13,
"minItems": 1,
"type": "array"
},
"subscriber_identifier_REF": {
"additionalProperties": false,
"description": "To specify identifying information",
"properties": {
"reference_identification_qualifier_01": {
"description": "Code qualifying the Reference Identification",
"enum": ["0F"],
"title": "Reference Identification Qualifier",
"type": "string",
"x12-codes": {
"0F": {
"description": "Subscriber Number",
"code": "0F",
"x12-usage-notes": "The assignment of the Subscriber Number is designated within the Insurance Contract."
}
}
},
"subscriber_identifier_02": {
"description": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier",
"maxLength": 50,
"minLength": 1,
"title": "Subscriber Identifier",
"type": "string"
}
},
"required": [
"reference_identification_qualifier_01",
"subscriber_identifier_02"
],
"title": "Subscriber Identifier",
"type": "object",
"x12-usage-notes": "- This segment must contain a unique SUBSCRIBER identification number (SSN or other). This occurrence is identified by the 0F qualifier (REF01). This identifier is used for linking the subscriber with dependents as required under many policies.\n- The developers recommend using the identifier developed under the HIPAA legislation, when that becomes available."
},
"member_level_dates_DTP": {
"items": {
"additionalProperties": false,
"description": "To specify any or all of a date, a time, or a time period",
"properties": {
"date_time_qualifier_01": {
"description": "Code specifying type of date or time, or both date and time",
"enum": [
"050",
"286",
"296",
"297",
"300",
"301",
"303",
"336",
"337",
"338",
"339",
"340",
"341",
"350",
"351",
"356",
"357",
"383",
"385",
"386",
"393",
"394",
"473",
"474"
],
"title": "Date Time Qualifier",
"type": "string",
"x12-codes": {
"286": {
"description": "Retirement",
"code": "286"
},
"296": {
"description": "Initial Disability Period Return To Work",
"code": "296"
},
"297": {
"description": "Initial Disability Period Last Day Worked",
"code": "297"
},
"300": {
"description": "Enrollment Signature Date",
"code": "300"
},
"301": {
"description": "Consolidated Omnibus Budget Reconciliation Act (COBRA) Qualifying Event",
"code": "301"
},
"303": {
"description": "Maintenance Effective",
"code": "303",
"x12-usage-notes": "This code is used to send the effective date of a change to an existing member's information, excluding changes made in Loop 2300."
},
"336": {
"description": "Employment Begin",
"code": "336"
},
"337": {
"description": "Employment End",
"code": "337"
},
"338": {
"description": "Medicare Begin",
"code": "338"
},
"339": {
"description": "Medicare End",
"code": "339"
},
"340": {
"description": "Consolidated Omnibus Budget Reconciliation Act (COBRA) Begin",
"code": "340"
},
"341": {
"description": "Consolidated Omnibus Budget Reconciliation Act (COBRA) End",
"code": "341"
},
"350": {
"description": "Education Begin",
"code": "350",
"x12-usage-notes": "This is the start date for the student at the current educational institution."
},
"351": {
"description": "Education End",
"code": "351",
"x12-usage-notes": "This is the expected graduation date the student at the current educational institution."
},
"356": {
"description": "Eligibility Begin",
"code": "356",
"x12-usage-notes": "The date when a member could elect to enroll or begin benefits in any health care plan through the employer. This is not the actual begin date of coverage, which is conveyed in the DTP segment at position 2700."
},
"357": {
"description": "Eligibility End",
"code": "357",
"x12-usage-notes": "The eligibility end date represents the last date of coverage for which claims will be paid for the individual being terminated. For example, if a date of 02/28/2001 is passed then claims for this individual will be paid through 11:59 p.m. on 02/28/2001."
},
"383": {
"description": "Adjusted Hire",
"code": "383"
},
"385": {
"description": "Credited Service Begin",
"code": "385",
"x12-usage-notes": "The start date from which an employee's length of service, as defined in the plan document, will be calculated."
},
"386": {
"description": "Credited Service End",
"code": "386",
"x12-usage-notes": "The end date to be used in the calculation of an employee's length of service, as defined in the plan document."
},
"393": {
"description": "Plan Participation Suspension",
"code": "393"
},
"394": {
"description": "Rehire",
"code": "394"
},
"473": {
"description": "Medicaid Begin",
"code": "473"
},
"474": {
"description": "Medicaid End",
"code": "474"
},
"050": {
"description": "Received",
"code": "050",
"x12-usage-notes": "Used to identify the date an enrollment application is received."
}
}
},
"date_time_period_format_qualifier_02": {
"description": "Code indicating the date format, time format, or date and time format\n\n- DTP02 is the date or time or period format that will appear in DTP03.",
"enum": ["D8"],
"title": "Date Time Period Format Qualifier",
"type": "string",
"x12-codes": {
"D8": {
"description": "Date Expressed in Format CCYYMMDD",
"code": "D8"
}
}
},
"status_information_effective_date_03": {
"description": "Expression of a date, a time, or range of dates, times or dates and times",
"maxLength": 35,
"minLength": 1,
"title": "Status Information Effective Date",
"type": "string"
}
},
"required": [
"date_time_qualifier_01",
"date_time_period_format_qualifier_02",
"status_information_effective_date_03"
],
"title": "Member Level Dates",
"type": "object",
"x12-usage-notes": "- Required when enrolling a member or when the sponsor is informed of a change to any applicable date listed in DTP01. Only those dates that apply to the particular insurance contract need to be sent. If not required by this implementation guide, do not send.\n- While many of the dates listed for DTP01 are related to termination, the only code that is used to actually terminate a Member is 357 (Eligibility End). Similarly, the Eligibility Begin Date (code 356) is the date the individual is eligible for coverage, not the date coverage is effective."
},
"maxItems": 24,
"minItems": 1,
"type": "array"
},
"member_name_NM1_loop": {
"additionalProperties": false,
"properties": {
"member_name_NM1": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0809",
"type": "object",
"dependentRequired": {
"identification_code_qualifier_08": [
"member_identifier_09"
],
"member_identifier_09": [
"identification_code_qualifier_08"
]
}
}
],
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["74", "IL"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"74": {
"description": "Corrected Insured",
"code": "74",
"x12-usage-notes": "Use this code if this transmission is correcting the identifier information on a member already enrolled. Usage of this code requires the sending of an NM1 with code '70' in loop 2100B."
},
"IL": {
"description": "Insured or Subscriber",
"code": "IL",
"x12-usage-notes": "Use this code for enrolling a new member or updating a member with no change in identifying information. The identifying information for a member is specified under the insurance contract between the sponsor and payer."
}
},
"x12-usage-notes": "- This code identifies if this is a correction to a previous enrollment or if it is a new, or update, enrollment transaction."
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["1"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"1": {
"description": "Person",
"code": "1"
}
}
},
"member_last_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "Member Last Name",
"type": "string"
},
"member_first_name_04": {
"description": "Individual first name",
"maxLength": 35,
"minLength": 1,
"title": "Member First Name",
"type": "string"
},
"member_middle_name_05": {
"description": "Individual middle name or initial",
"maxLength": 25,
"minLength": 1,
"title": "Member Middle Name",
"type": "string"
},
"member_name_prefix_06": {
"description": "Prefix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Member Name Prefix",
"type": "string"
},
"member_name_suffix_07": {
"description": "Suffix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Member Name Suffix",
"type": "string"
},
"identification_code_qualifier_08": {
"description": "Code designating the system/method of code structure used for Identification Code (67)",
"enum": ["34", "ZZ"],
"title": "Identification Code Qualifier",
"type": "string",
"x12-codes": {
"34": {
"description": "Social Security Number",
"code": "34",
"x12-usage-notes": "The social security number may not be used for any Federally administered programs such as Medicare or CHAMPUS/TRICARE."
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ",
"x12-usage-notes": "Value is required if National Individual Identifier is mandated for use. Otherwise, one of the other listed codes may be used."
}
}
},
"member_identifier_09": {
"description": "Code identifying a party or other code",
"maxLength": 80,
"minLength": 2,
"title": "Member Identifier",
"type": "string"
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02",
"member_last_name_03"
],
"title": "Member Name",
"type": "object",
"x12-usage-notes": ""
},
"member_communications_numbers_PER": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0506",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_05": [
"communication_number_06"
],
"communication_number_06": [
"communication_number_qualifier_05"
]
}
},
{
"x12-condition": "P0708",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_07": [
"communication_number_08"
],
"communication_number_08": [
"communication_number_qualifier_07"
]
}
}
],
"description": "To identify a person or office to whom administrative communications should be directed",
"properties": {
"contact_function_code_01": {
"description": "Code identifying the major duty or responsibility of the person or group named",
"enum": ["IP"],
"title": "Contact Function Code",
"type": "string",
"x12-codes": {
"IP": {
"description": "Insured Party",
"code": "IP"
}
}
},
"communication_number_qualifier_03": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_04": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_05": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_06": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_07": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_08": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
}
},
"required": [
"contact_function_code_01",
"communication_number_qualifier_03",
"communication_number_04"
],
"title": "Member Communications Numbers",
"type": "object",
"x12-usage-notes": "- When the communication number represents a telephone number in the United States and other countries using the North American Dialing Plan (for voice, data, fax, etc.), the communication number always includes the area code and phone number using the format AAABBBCCCC, where AAA is the area code, BBB is the telephone number prefix, and CCCC is the telephone number (e.g. (534)224-2525 would be represented as 5342242525).\n- Required when enrolling subscribers, dependents with different contact information, or when changing a member's contact information and the information is provided to the sponsor for the member. If not required by this implementation guide, do not send."
},
"member_residence_street_address_N3": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"member_address_line_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Member Address Line",
"type": "string"
},
"member_address_line_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Member Address Line",
"type": "string"
}
},
"required": ["member_address_line_01"],
"title": "Member Residence Street Address",
"type": "object",
"x12-usage-notes": "- Required when enrolling subscribers, dependents with different address information, or when changing a member's address. If not required by this implementation guide, do not send."
},
"member_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": ["member_state_code_02"],
"type": "object",
"properties": {
"member_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": ["member_state_code_02"],
"type": "object",
"properties": {
"member_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0605",
"dependentRequired": {
"location_identifier_06": ["location_qualifier_05"]
}
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": ["country_code_04"]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"member_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Member City Name",
"type": "string"
},
"member_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Member State Code",
"type": "string"
},
"member_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Member Postal Zone or Zip Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"location_qualifier_05": {
"description": "Code identifying type of location",
"enum": ["60", "CY"],
"title": "Location Qualifier",
"type": "string",
"x12-codes": {
"60": {
"description": "Area",
"code": "60"
},
"CY": {
"description": "County/Parish",
"code": "CY"
}
}
},
"location_identifier_06": {
"description": "Code which identifies a specific location",
"maxLength": 30,
"minLength": 1,
"title": "Location Identifier",
"type": "string"
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": ["member_city_name_01"],
"title": "Member City, State, ZIP Code",
"type": "object",
"x12-usage-notes": "- Required when enrolling subscribers, dependents with different address information, or when changing a member's address. If not required by this implementation guide, do not send."
},
"member_demographics_DMG": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P1011",
"type": "object",
"dependentRequired": {
"code_list_qualifier_code_10": [
"race_or_ethnicity_collection_code_11"
],
"race_or_ethnicity_collection_code_11": [
"code_list_qualifier_code_10"
]
}
},
{
"type": "object",
"x12-condition": "C1105",
"dependentRequired": {
"race_or_ethnicity_collection_code_11": [
"composite_race_or_ethnicity_information_05"
]
}
}
],
"description": "To supply demographic information",
"properties": {
"date_time_period_format_qualifier_01": {
"description": "Code indicating the date format, time format, or date and time format",
"enum": ["D8"],
"title": "Date Time Period Format Qualifier",
"type": "string",
"x12-codes": {
"D8": {
"description": "Date Expressed in Format CCYYMMDD",
"code": "D8"
}
}
},
"member_birth_date_02": {
"description": "Expression of a date, a time, or range of dates, times or dates and times\n\n- DMG02 is the date of birth.",
"maxLength": 35,
"minLength": 1,
"title": "Member Birth Date",
"type": "string"
},
"gender_code_03": {
"description": "Code indicating the sex of the individual",
"enum": ["F", "M", "U"],
"title": "Gender Code",
"type": "string",
"x12-codes": {
"F": {
"description": "Female",
"code": "F"
},
"M": {
"description": "Male",
"code": "M"
},
"U": {
"description": "Unknown",
"code": "U",
"x12-usage-notes": "This code is to be used only when the gender is unknown or when it can not be sent due to reporting restrictions."
}
}
},
"marital_status_code_04": {
"description": "Code defining the marital status of a person",
"enum": ["B", "D", "I", "M", "R", "S", "U", "W", "X"],
"title": "Marital Status Code",
"type": "string",
"x12-codes": {
"B": {
"description": "Registered Domestic Partner",
"code": "B"
},
"D": {
"description": "Divorced",
"code": "D"
},
"I": {
"description": "Single",
"code": "I"
},
"M": {
"description": "Married",
"code": "M"
},
"R": {
"description": "Unreported",
"code": "R"
},
"S": {
"description": "Separated",
"code": "S"
},
"U": {
"description": "Unmarried (Single or Divorced or Widowed)",
"code": "U",
"x12-usage-notes": "This code should be used if the previous status is unknown."
},
"W": {
"description": "Widowed",
"code": "W"
},
"X": {
"description": "Legally Separated",
"code": "X"
}
}
},
"composite_race_or_ethnicity_information_05": {
"type": "array",
"items": {
"allOf": [
{
"x12-condition": "P0203",
"type": "object",
"dependentRequired": {
"code_list_qualifier_code_02": [
"race_or_ethnicity_code_03"
],
"race_or_ethnicity_code_03": [
"code_list_qualifier_code_02"
]
}
}
],
"description": "To send general and detailed information on race or ethnicity",
"properties": {
"race_or_ethnicity_code_01": {
"description": "Code indicating the racial or ethnic background of a person; it is normally self-reported; Under certain circumstances this information is collected for United States Government statistical purposes",
"enum": [
"7",
"8",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"N",
"O",
"P",
"Z"
],
"title": "Race or Ethnicity Code",
"type": "string",
"x12-codes": {
"7": {
"description": "Not Provided",
"code": "7"
},
"8": {
"description": "Not Applicable",
"code": "8"
},
"A": {
"description": "Asian or Pacific Islander",
"code": "A"
},
"B": {
"description": "Black",
"code": "B"
},
"C": {
"description": "Caucasian",
"code": "C"
},
"D": {
"description": "Subcontinent Asian American",
"code": "D"
},
"E": {
"description": "Other Race or Ethnicity",
"code": "E"
},
"F": {
"description": "Asian Pacific American",
"code": "F"
},
"G": {
"description": "Native American",
"code": "G"
},
"H": {
"description": "Hispanic",
"code": "H"
},
"I": {
"description": "American Indian or Alaskan Native",
"code": "I"
},
"J": {
"description": "Native Hawaiian",
"code": "J"
},
"N": {
"description": "Black (Non-Hispanic)",
"code": "N"
},
"O": {
"description": "White (Non-Hispanic)",
"code": "O"
},
"P": {
"description": "Pacific Islander",
"code": "P"
},
"Z": {
"description": "Mutually Defined",
"code": "Z"
}
}
},
"code_list_qualifier_code_02": {
"description": "Code identifying a specific industry code list\n\n- C056-02 and C056-03 are used to specify detailed information about race or ethnicity.",
"enum": ["RET"],
"title": "Code List Qualifier Code",
"type": "string",
"x12-codes": {
"RET": {
"description": "Classification of Race or Ethnicity",
"code": "RET"
}
}
},
"race_or_ethnicity_code_03": {
"description": "Code indicating a code from a specific industry code list",
"maxLength": 30,
"minLength": 1,
"title": "Race or Ethnicity Code",
"type": "string",
"x12-usage-notes": "- CODE SOURCE 859: Classification of Race or Ethnicity"
}
},
"title": "Composite Race or Ethnicity Information",
"type": "object",
"x12-usage-notes": "Required when such transmission is required under the insurance contract between the sponsor and payer and allowed by federal and state regulations. If not required by this implementation guide, do not send."
},
"minItems": 1,
"maxItems": 10
},
"citizenship_status_code_06": {
"description": "Code indicating citizenship status",
"enum": ["1", "2", "3", "4", "5", "6", "7"],
"title": "Citizenship Status Code",
"type": "string",
"x12-codes": {
"1": {
"description": "U.S. Citizen",
"code": "1"
},
"2": {
"description": "Non-Resident Alien",
"code": "2"
},
"3": {
"description": "Resident Alien",
"code": "3"
},
"4": {
"description": "Illegal Alien",
"code": "4"
},
"5": {
"description": "Alien",
"code": "5"
},
"6": {
"description": "U.S. Citizen - Non-Resident",
"code": "6"
},
"7": {
"description": "U.S. Citizen - Resident",
"code": "7"
}
}
},
"code_list_qualifier_code_10": {
"description": "Code identifying a specific industry code list",
"enum": ["REC"],
"title": "Code List Qualifier Code",
"type": "string",
"x12-codes": {
"REC": {
"description": "Race or Ethnicity Collection Code",
"code": "REC"
}
}
},
"race_or_ethnicity_collection_code_11": {
"description": "Code indicating a code from a specific industry code list\n\n- DMG11 is used to specify how the information in DMG05, including repeats of C056, was collected.",
"maxLength": 30,
"minLength": 1,
"title": "Race or Ethnicity Collection Code",
"type": "string"
}
},
"required": [
"date_time_period_format_qualifier_01",
"member_birth_date_02",
"gender_code_03"
],
"title": "Member Demographics",
"type": "object",
"x12-usage-notes": "- Required when enrolling a new member, changing a member's demographic information, or terminating a member. If not required by this implementation guide, do not send."
},
"employment_class_EC": {
"items": {
"additionalProperties": false,
"description": "To provide class of employment information",
"properties": {
"employment_class_code_01": {
"description": "Code indicating category of employee",
"enum": [
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"12",
"17",
"18",
"19",
"20",
"21",
"22",
"23"
],
"title": "Employment Class Code",
"type": "string",
"x12-codes": {
"10": {
"description": "Non-Administrative",
"code": "10"
},
"11": {
"description": "Exempt",
"code": "11"
},
"12": {
"description": "Non-Exempt",
"code": "12"
},
"17": {
"description": "Highly Compensated",
"code": "17"
},
"18": {
"description": "Key-Employee",
"code": "18"
},
"19": {
"description": "Bargaining",
"code": "19"
},
"20": {
"description": "Non-Bargaining",
"code": "20"
},
"21": {
"description": "Owner",
"code": "21"
},
"22": {
"description": "President",
"code": "22"
},
"23": {
"description": "Vice President",
"code": "23"
},
"01": {
"description": "Union",
"code": "01"
},
"02": {
"description": "Non-Union",
"code": "02"
},
"03": {
"description": "Executive",
"code": "03"
},
"04": {
"description": "Non-Executive",
"code": "04"
},
"05": {
"description": "Management",
"code": "05"
},
"06": {
"description": "Non-Management",
"code": "06"
},
"07": {
"description": "Hourly",
"code": "07"
},
"08": {
"description": "Salaried",
"code": "08"
},
"09": {
"description": "Administrative",
"code": "09"
}
}
},
"employment_class_code_02": {
"description": "Code indicating category of employee",
"enum": [
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"12",
"17",
"18",
"19",
"20",
"21",
"22",
"23"
],
"title": "Employment Class Code",
"type": "string",
"x12-codes": {
"10": {
"description": "Non-Administrative",
"code": "10"
},
"11": {
"description": "Exempt",
"code": "11"
},
"12": {
"description": "Non-Exempt",
"code": "12"
},
"17": {
"description": "Highly Compensated",
"code": "17"
},
"18": {
"description": "Key-Employee",
"code": "18"
},
"19": {
"description": "Bargaining",
"code": "19"
},
"20": {
"description": "Non-Bargaining",
"code": "20"
},
"21": {
"description": "Owner",
"code": "21"
},
"22": {
"description": "President",
"code": "22"
},
"23": {
"description": "Vice President",
"code": "23"
},
"01": {
"description": "Union",
"code": "01"
},
"02": {
"description": "Non-Union",
"code": "02"
},
"03": {
"description": "Executive",
"code": "03"
},
"04": {
"description": "Non-Executive",
"code": "04"
},
"05": {
"description": "Management",
"code": "05"
},
"06": {
"description": "Non-Management",
"code": "06"
},
"07": {
"description": "Hourly",
"code": "07"
},
"08": {
"description": "Salaried",
"code": "08"
},
"09": {
"description": "Administrative",
"code": "09"
}
}
},
"employment_class_code_03": {
"description": "Code indicating category of employee",
"enum": [
"01",
"02",
"03",
"04",
"05",
"06",
"07",
"08",
"09",
"10",
"11",
"12",
"17",
"18",
"19",
"20",
"21",
"22",
"23"
],
"title": "Employment Class Code",
"type": "string",
"x12-codes": {
"10": {
"description": "Non-Administrative",
"code": "10"
},
"11": {
"description": "Exempt",
"code": "11"
},
"12": {
"description": "Non-Exempt",
"code": "12"
},
"17": {
"description": "Highly Compensated",
"code": "17"
},
"18": {
"description": "Key-Employee",
"code": "18"
},
"19": {
"description": "Bargaining",
"code": "19"
},
"20": {
"description": "Non-Bargaining",
"code": "20"
},
"21": {
"description": "Owner",
"code": "21"
},
"22": {
"description": "President",
"code": "22"
},
"23": {
"description": "Vice President",
"code": "23"
},
"01": {
"description": "Union",
"code": "01"
},
"02": {
"description": "Non-Union",
"code": "02"
},
"03": {
"description": "Executive",
"code": "03"
},
"04": {
"description": "Non-Executive",
"code": "04"
},
"05": {
"description": "Management",
"code": "05"
},
"06": {
"description": "Non-Management",
"code": "06"
},
"07": {
"description": "Hourly",
"code": "07"
},
"08": {
"description": "Salaried",
"code": "08"
},
"09": {
"description": "Administrative",
"code": "09"
}
}
}
},
"required": ["employment_class_code_01"],
"title": "Employment Class",
"type": "object",
"x12-usage-notes": "- Required when sending additional employment class information on the member. If not required by this implementation guide, do not send."
},
"minItems": 1,
"type": "array"
},
"member_income_ICM": {
"additionalProperties": false,
"description": "To supply information to determine benefit eligibility, deductibles, and retirement and investment contributions",
"properties": {
"frequency_code_01": {
"description": "Code indicating frequency or type of activities or actions being reported\n\n- ICM01 is the frequency at which an individual's wages are paid.",
"enum": [
"1",
"2",
"3",
"4",
"6",
"7",
"8",
"9",
"B",
"C",
"H",
"Q",
"S",
"U"
],
"title": "Frequency Code",
"type": "string",
"x12-codes": {
"1": {
"description": "Weekly",
"code": "1"
},
"2": {
"description": "Biweekly",
"code": "2"
},
"3": {
"description": "Semimonthly",
"code": "3"
},
"4": {
"description": "Monthly",
"code": "4"
},
"6": {
"description": "Daily",
"code": "6"
},
"7": {
"description": "Annual",
"code": "7"
},
"8": {
"description": "Two Calendar Months",
"code": "8"
},
"9": {
"description": "Lump-Sum Separation Allowance",
"code": "9"
},
"B": {
"description": "Year-to-Date",
"code": "B"
},
"C": {
"description": "Single",
"code": "C"
},
"H": {
"description": "Hourly",
"code": "H"
},
"Q": {
"description": "Quarterly",
"code": "Q"
},
"S": {
"description": "Semiannual",
"code": "S"
},
"U": {
"description": "Unknown",
"code": "U"
}
}
},
"wage_amount_02": {
"description": "Monetary amount\n\n- ICM02 is the yearly wages amount.",
"title": "Wage Amount",
"type": "number",
"x12-max-length": 15
},
"work_hours_count_03": {
"description": "Numeric value of quantity\n\n- ICM03 is the weekly hours.",
"title": "Work Hours Count",
"type": "number",
"x12-max-length": 15
},
"location_identification_code_04": {
"description": "Code which identifies a specific location\n\n- ICM04 is the employer location qualifier such as a department number.",
"maxLength": 30,
"minLength": 1,
"title": "Location Identification Code",
"type": "string"
},
"salary_grade_code_05": {
"description": "The salary grade code assigned by the employer",
"maxLength": 5,
"minLength": 1,
"title": "Salary Grade Code",
"type": "string"
}
},
"required": ["frequency_code_01", "wage_amount_02"],
"title": "Member Income",
"type": "object",
"x12-usage-notes": "- Required when such transmission is required under the insurance contract between the sponsor and payer. If not required by this implementation guide, do not send."
},
"member_policy_amounts_AMT": {
"items": {
"additionalProperties": false,
"description": "To indicate the total monetary amount",
"properties": {
"amount_qualifier_code_01": {
"description": "Code to qualify amount",
"enum": ["B9", "C1", "D2", "EBA", "FK", "P3", "R"],
"title": "Amount Qualifier Code",
"type": "string",
"x12-codes": {
"B9": {
"description": "Co-insurance - Actual",
"code": "B9",
"x12-usage-notes": "This will contain any co-insurance selection amount. The option of adjusting this amount to produce the actual co-insurance can be defined in the insurance contract."
},
"C1": {
"description": "Co-Payment Amount",
"code": "C1"
},
"D2": {
"description": "Deductible Amount",
"code": "D2"
},
"EBA": {
"description": "Expected Expenditure Amount",
"code": "EBA"
},
"FK": {
"description": "Other Unlisted Amount",
"code": "FK"
},
"P3": {
"description": "Premium Amount",
"code": "P3"
},
"R": {
"description": "Spend Down",
"code": "R"
}
}
},
"contract_amount_02": {
"description": "Monetary amount",
"title": "Contract Amount",
"type": "number",
"x12-max-length": 15
}
},
"required": [
"amount_qualifier_code_01",
"contract_amount_02"
],
"title": "Member Policy Amounts",
"type": "object",
"x12-usage-notes": "- Required when such transmission is required under the insurance contract between the sponsor and payer. If not required by this implementation guide, do not send."
},
"maxItems": 7,
"minItems": 1,
"type": "array"
},
"member_health_information_HLH": {
"additionalProperties": false,
"description": "To provide health information",
"properties": {
"health_related_code_01": {
"description": "Code indicating a specific health situation",
"enum": ["N", "S", "T", "U", "X"],
"title": "Health Related Code",
"type": "string",
"x12-codes": {
"N": {
"description": "None",
"code": "N"
},
"S": {
"description": "Substance Abuse",
"code": "S"
},
"T": {
"description": "Tobacco Use",
"code": "T"
},
"U": {
"description": "Unknown",
"code": "U"
},
"X": {
"description": "Tobacco Use and Substance Abuse",
"code": "X"
}
}
},
"member_height_02": {
"description": "Vertical dimension of an object measured when the object is in the upright position",
"title": "Member Height",
"type": "number",
"x12-usage-notes": "- The height must be reported in inches.",
"x12-max-length": 8
},
"member_weight_03": {
"description": "Numeric value of weight\n\n- HLH03 is the current weight in pounds.",
"title": "Member Weight",
"type": "number",
"x12-max-length": 10
}
},
"required": ["health_related_code_01"],
"title": "Member Health Information",
"type": "object",
"x12-usage-notes": "- Required on initial enrollment of a member when appropriate medical information about the member is available. If not required by this implementation guide, do not send."
},
"member_language_LUI": {
"items": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0102",
"type": "object",
"dependentRequired": {
"identification_code_qualifier_01": [
"language_code_02"
],
"language_code_02": ["identification_code_qualifier_01"]
}
},
{
"x12-condition": "L040203",
"anyOf": [
{
"dependentRequired": {
"language_use_indicator_04": ["language_code_02"]
},
"type": "object"
},
{
"dependentRequired": {
"language_use_indicator_04": [
"language_description_03"
]
},
"type": "object"
}
]
}
],
"description": "To specify language, type of usage, and proficiency or fluency",
"properties": {
"identification_code_qualifier_01": {
"description": "Code designating the system/method of code structure used for Identification Code (67)",
"enum": ["LD", "LE"],
"title": "Identification Code Qualifier",
"type": "string",
"x12-codes": {
"LD": {
"description": "NISO Z39.53 Language Codes",
"code": "LD"
},
"LE": {
"description": "ISO 639 Language Codes",
"code": "LE"
}
}
},
"language_code_02": {
"description": "Code identifying a party or other code\n\n- LUI02 is the language code.",
"maxLength": 80,
"minLength": 2,
"title": "Language Code",
"type": "string"
},
"language_description_03": {
"description": "A free-form description to clarify the related data elements and their content\n\n- LUI03 is the name of the language.",
"maxLength": 80,
"minLength": 1,
"title": "Language Description",
"type": "string"
},
"language_use_indicator_04": {
"description": "Code indicating the use of a language",
"enum": ["5", "6", "7", "8"],
"title": "Language Use Indicator",
"type": "string",
"x12-codes": {
"5": {
"description": "Language Reading",
"code": "5"
},
"6": {
"description": "Language Writing",
"code": "6"
},
"7": {
"description": "Language Speaking",
"code": "7"
},
"8": {
"description": "Native Language",
"code": "8"
}
}
}
},
"title": "Member Language",
"type": "object",
"x12-usage-notes": "- Required if the sponsor knows that the member's primary language is not English, and such transmission is required under the insurance contract between the sponsor and payer and allowed by federal and state regulations. If not required by this implementation guide do not send.\n- Any need to send/collect this information will need to be contained in the trading partner agreement."
},
"minItems": 1,
"type": "array"
}
},
"required": ["member_name_NM1"],
"title": "Member Name Loop",
"type": "object"
},
"incorrect_member_name_NM1_loop": {
"additionalProperties": false,
"properties": {
"incorrect_member_name_NM1": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0809",
"type": "object",
"dependentRequired": {
"identification_code_qualifier_08": [
"prior_incorrect_insured_identifier_09"
],
"prior_incorrect_insured_identifier_09": [
"identification_code_qualifier_08"
]
}
}
],
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["70"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"70": {
"description": "Prior Incorrect Insured",
"code": "70"
}
},
"x12-usage-notes": "- This code identifies that the information that follows is previously reported enrollment information that is being corrected."
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["1"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"1": {
"description": "Person",
"code": "1"
}
}
},
"prior_incorrect_member_last_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "Prior Incorrect Member Last Name",
"type": "string"
},
"prior_incorrect_member_first_name_04": {
"description": "Individual first name",
"maxLength": 35,
"minLength": 1,
"title": "Prior Incorrect Member First Name",
"type": "string"
},
"prior_incorrect_member_middle_name_05": {
"description": "Individual middle name or initial",
"maxLength": 25,
"minLength": 1,
"title": "Prior Incorrect Member Middle Name",
"type": "string"
},
"prior_incorrect_member_name_prefix_06": {
"description": "Prefix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Prior Incorrect Member Name Prefix",
"type": "string"
},
"prior_incorrect_member_name_suffix_07": {
"description": "Suffix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Prior Incorrect Member Name Suffix",
"type": "string"
},
"identification_code_qualifier_08": {
"description": "Code designating the system/method of code structure used for Identification Code (67)",
"enum": ["34", "ZZ"],
"title": "Identification Code Qualifier",
"type": "string",
"x12-codes": {
"34": {
"description": "Social Security Number",
"code": "34",
"x12-usage-notes": "The social security number may not be used for any Federally administered programs such as Medicare or CHAMPUS/TRICARE."
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ",
"x12-usage-notes": "Value is required if National Individual Identifier is mandated for use. Otherwise, one of the other listed codes may be used."
}
}
},
"prior_incorrect_insured_identifier_09": {
"description": "Code identifying a party or other code",
"maxLength": 80,
"minLength": 2,
"title": "Prior Incorrect Insured Identifier",
"type": "string",
"x12-usage-notes": "- NM109 is the identifier that was previously sent in error. This allows matching with data on receiver's system."
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02",
"prior_incorrect_member_last_name_03"
],
"title": "Incorrect Member Name",
"type": "object",
"x12-usage-notes": "- Required if a corrected name is being sent in loop 2100A or if previously supplied demographics are being changed. If only the demographics are being changed, the code in NM101 in loop 2100A will be IL, and the code in NM101 in this loop will be 70. If not required by this implementation guide, do not send.\n- If only the demographics are being changed, the code in NM101 in loop 2100A will be IL, and the code in NM101 in this loop will be 70."
},
"incorrect_member_demographics_DMG": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0102",
"type": "object",
"dependentRequired": {
"date_time_period_format_qualifier_01": [
"prior_incorrect_insured_birth_date_02"
],
"prior_incorrect_insured_birth_date_02": [
"date_time_period_format_qualifier_01"
]
}
},
{
"x12-condition": "P1011",
"type": "object",
"dependentRequired": {
"code_list_qualifier_code_10": [
"race_or_ethnicity_collection_code_11"
],
"race_or_ethnicity_collection_code_11": [
"code_list_qualifier_code_10"
]
}
},
{
"type": "object",
"x12-condition": "C1105",
"dependentRequired": {
"race_or_ethnicity_collection_code_11": [
"composite_race_or_ethnicity_information_05"
]
}
}
],
"description": "To supply demographic information",
"properties": {
"date_time_period_format_qualifier_01": {
"description": "Code indicating the date format, time format, or date and time format",
"enum": ["D8"],
"title": "Date Time Period Format Qualifier",
"type": "string",
"x12-codes": {
"D8": {
"description": "Date Expressed in Format CCYYMMDD",
"code": "D8"
}
}
},
"prior_incorrect_insured_birth_date_02": {
"description": "Expression of a date, a time, or range of dates, times or dates and times\n\n- DMG02 is the date of birth.",
"maxLength": 35,
"minLength": 1,
"title": "Prior Incorrect Insured Birth Date",
"type": "string"
},
"prior_incorrect_insured_gender_code_03": {
"description": "Code indicating the sex of the individual",
"enum": ["F", "M", "U"],
"title": "Prior Incorrect Insured Gender Code",
"type": "string",
"x12-codes": {
"F": {
"description": "Female",
"code": "F"
},
"M": {
"description": "Male",
"code": "M"
},
"U": {
"description": "Unknown",
"code": "U"
}
}
},
"marital_status_code_04": {
"description": "Code defining the marital status of a person",
"enum": ["B", "D", "I", "M", "R", "S", "U", "W", "X"],
"title": "Marital Status Code",
"type": "string",
"x12-codes": {
"B": {
"description": "Registered Domestic Partner",
"code": "B"
},
"D": {
"description": "Divorced",
"code": "D"
},
"I": {
"description": "Single",
"code": "I"
},
"M": {
"description": "Married",
"code": "M"
},
"R": {
"description": "Unreported",
"code": "R"
},
"S": {
"description": "Separated",
"code": "S"
},
"U": {
"description": "Unmarried (Single or Divorced or Widowed)",
"code": "U",
"x12-usage-notes": "This code should be used if the previous status is unknown."
},
"W": {
"description": "Widowed",
"code": "W"
},
"X": {
"description": "Legally Separated",
"code": "X"
}
}
},
"composite_race_or_ethnicity_information_05": {
"type": "array",
"items": {
"allOf": [
{
"x12-condition": "P0203",
"type": "object",
"dependentRequired": {
"code_list_qualifier_code_02": [
"race_or_ethnicity_code_03"
],
"race_or_ethnicity_code_03": [
"code_list_qualifier_code_02"
]
}
}
],
"description": "To send general and detailed information on race or ethnicity",
"properties": {
"race_or_ethnicity_code_01": {
"description": "Code indicating the racial or ethnic background of a person; it is normally self-reported; Under certain circumstances this information is collected for United States Government statistical purposes",
"enum": [
"7",
"8",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"N",
"O",
"P",
"Z"
],
"title": "Race or Ethnicity Code",
"type": "string",
"x12-codes": {
"7": {
"description": "Not Provided",
"code": "7"
},
"8": {
"description": "Not Applicable",
"code": "8"
},
"A": {
"description": "Asian or Pacific Islander",
"code": "A"
},
"B": {
"description": "Black",
"code": "B"
},
"C": {
"description": "Caucasian",
"code": "C"
},
"D": {
"description": "Subcontinent Asian American",
"code": "D"
},
"E": {
"description": "Other Race or Ethnicity",
"code": "E"
},
"F": {
"description": "Asian Pacific American",
"code": "F"
},
"G": {
"description": "Native American",
"code": "G"
},
"H": {
"description": "Hispanic",
"code": "H"
},
"I": {
"description": "American Indian or Alaskan Native",
"code": "I"
},
"J": {
"description": "Native Hawaiian",
"code": "J"
},
"N": {
"description": "Black (Non-Hispanic)",
"code": "N"
},
"O": {
"description": "White (Non-Hispanic)",
"code": "O"
},
"P": {
"description": "Pacific Islander",
"code": "P"
},
"Z": {
"description": "Mutually Defined",
"code": "Z"
}
}
},
"code_list_qualifier_code_02": {
"description": "Code identifying a specific industry code list\n\n- C056-02 and C056-03 are used to specify detailed information about race or ethnicity.",
"enum": ["RET"],
"title": "Code List Qualifier Code",
"type": "string",
"x12-codes": {
"RET": {
"description": "Classification of Race or Ethnicity",
"code": "RET"
}
}
},
"race_or_ethnicity_code_03": {
"description": "Code indicating a code from a specific industry code list",
"maxLength": 30,
"minLength": 1,
"title": "Race or Ethnicity Code",
"type": "string"
}
},
"title": "Composite Race or Ethnicity Information",
"type": "object",
"x12-usage-notes": "Required when the members Race or Ethnicity is being corrected. If not required this implementation guide, do not send."
},
"minItems": 1,
"maxItems": 10
},
"citizenship_status_code_06": {
"description": "Code indicating citizenship status",
"enum": ["1", "2", "3", "4", "5", "6", "7"],
"title": "Citizenship Status Code",
"type": "string",
"x12-codes": {
"1": {
"description": "U.S. Citizen",
"code": "1"
},
"2": {
"description": "Non-Resident Alien",
"code": "2"
},
"3": {
"description": "Resident Alien",
"code": "3"
},
"4": {
"description": "Illegal Alien",
"code": "4"
},
"5": {
"description": "Alien",
"code": "5"
},
"6": {
"description": "U.S. Citizen - Non-Resident",
"code": "6"
},
"7": {
"description": "U.S. Citizen - Resident",
"code": "7"
}
}
},
"code_list_qualifier_code_10": {
"description": "Code identifying a specific industry code list",
"enum": ["REC"],
"title": "Code List Qualifier Code",
"type": "string",
"x12-codes": {
"REC": {
"description": "Race or Ethnicity Collection Code",
"code": "REC"
}
}
},
"race_or_ethnicity_collection_code_11": {
"description": "Code indicating a code from a specific industry code list\n\n- DMG11 is used to specify how the information in DMG05, including repeats of C056, was collected.",
"maxLength": 30,
"minLength": 1,
"title": "Race or Ethnicity Collection Code",
"type": "string"
}
},
"title": "Incorrect Member Demographics",
"type": "object",
"x12-usage-notes": "- Required when there is a change to the previously supplied demographic information. If not required by this implementation guide, do not send."
}
},
"required": ["incorrect_member_name_NM1"],
"title": "Incorrect Member Name Loop",
"type": "object"
},
"member_mailing_address_NM1_loop": {
"additionalProperties": false,
"properties": {
"member_mailing_address_NM1": {
"additionalProperties": false,
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["31"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"31": {
"description": "Postal Mailing Address",
"code": "31"
}
}
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["1"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"1": {
"description": "Person",
"code": "1"
}
}
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02"
],
"title": "Member Mailing Address",
"type": "object",
"x12-usage-notes": "- Required when the member mailing address is different from the residence address sent in loop 2100A or when the dependent's address is different from the subscriber. If not required by this implementation guide, do not send."
},
"member_mail_street_address_N3": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"member_address_line_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Member Address Line",
"type": "string"
},
"member_address_line_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Member Address Line",
"type": "string"
}
},
"required": ["member_address_line_01"],
"title": "Member Mail Street Address",
"type": "object",
"x12-usage-notes": ""
},
"member_mail_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": ["member_mail_state_code_02"],
"type": "object",
"properties": {
"member_mail_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": ["member_mail_state_code_02"],
"type": "object",
"properties": {
"member_mail_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": ["country_code_04"]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"member_mail_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Member Mail City Name",
"type": "string"
},
"member_mail_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Member Mail State Code",
"type": "string"
},
"member_mail_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Member Mail Postal Zone or ZIP Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": ["member_mail_city_name_01"],
"title": "Member Mail City, State, ZIP Code",
"type": "object",
"x12-usage-notes": ""
}
},
"required": [
"member_mailing_address_NM1",
"member_mail_street_address_N3",
"member_mail_city_state_zip_code_N4"
],
"title": "Member Mailing Address Loop",
"type": "object"
},
"member_employer_NM1_loop": {
"items": {
"additionalProperties": false,
"properties": {
"member_employer_NM1": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0809",
"type": "object",
"dependentRequired": {
"identification_code_qualifier_08": [
"member_employer_identifier_09"
],
"member_employer_identifier_09": [
"identification_code_qualifier_08"
]
}
}
],
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["36"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"36": {
"description": "Employer",
"code": "36"
}
}
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["1", "2"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"1": {
"description": "Person",
"code": "1"
},
"2": {
"description": "Non-Person Entity",
"code": "2"
}
}
},
"member_employer_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "Member Employer Name",
"type": "string"
},
"member_employer_first_name_04": {
"description": "Individual first name",
"maxLength": 35,
"minLength": 1,
"title": "Member Employer First Name",
"type": "string"
},
"member_employer_middle_name_05": {
"description": "Individual middle name or initial",
"maxLength": 25,
"minLength": 1,
"title": "Member Employer Middle Name",
"type": "string"
},
"member_employer_name_prefix_06": {
"description": "Prefix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Member Employer Name Prefix",
"type": "string"
},
"member_employer_name_suffix_07": {
"description": "Suffix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Member Employer Name Suffix",
"type": "string"
},
"identification_code_qualifier_08": {
"description": "Code designating the system/method of code structure used for Identification Code (67)",
"enum": ["24", "34"],
"title": "Identification Code Qualifier",
"type": "string",
"x12-codes": {
"24": {
"description": "Employer's Identification Number",
"code": "24",
"x12-usage-notes": "This is the \"HIPAA Employer Identifier\"."
},
"34": {
"description": "Social Security Number",
"code": "34"
}
}
},
"member_employer_identifier_09": {
"description": "Code identifying a party or other code",
"maxLength": 80,
"minLength": 2,
"title": "Member Employer Identifier",
"type": "string"
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02"
],
"title": "Member Employer",
"type": "object",
"x12-usage-notes": "- Required when the member is employed by someone other than the sponsor and the insurance contract requires the payer to be notified of such employment. If not required by this implementation guide, do not send.\n- This segment is not used to collect Coordination of Benefits (COB) information. COB information must be passed in the 2320 loop."
},
"member_employer_communications_numbers_PER": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0506",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_05": [
"communication_number_06"
],
"communication_number_06": [
"communication_number_qualifier_05"
]
}
},
{
"x12-condition": "P0708",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_07": [
"communication_number_08"
],
"communication_number_08": [
"communication_number_qualifier_07"
]
}
}
],
"description": "To identify a person or office to whom administrative communications should be directed",
"properties": {
"contact_function_code_01": {
"description": "Code identifying the major duty or responsibility of the person or group named",
"enum": ["EP"],
"title": "Contact Function Code",
"type": "string",
"x12-codes": {
"EP": {
"description": "Employer Contact",
"code": "EP"
}
}
},
"member_employer_communications_contact_name_02": {
"description": "Free-form name",
"maxLength": 60,
"minLength": 1,
"title": "Member Employer Communications Contact Name",
"type": "string"
},
"communication_number_qualifier_03": {
"description": "Code identifying the type of communication number",
"enum": ["AP", "BN", "CP", "EM", "EX", "FX", "TE"],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"TE": {
"description": "Telephone",
"code": "TE"
}
}
},
"communication_number_04": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_05": {
"description": "Code identifying the type of communication number",
"enum": ["AP", "BN", "CP", "EM", "EX", "FX", "TE"],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"TE": {
"description": "Telephone",
"code": "TE"
}
}
},
"communication_number_06": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_07": {
"description": "Code identifying the type of communication number",
"enum": ["AP", "BN", "CP", "EM", "EX", "FX", "TE"],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"TE": {
"description": "Telephone",
"code": "TE"
}
}
},
"communication_number_08": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
}
},
"required": [
"contact_function_code_01",
"communication_number_qualifier_03",
"communication_number_04"
],
"title": "Member Employer Communications Numbers",
"type": "object",
"x12-usage-notes": "- When the communication number represents a telephone number in the United States and other countries using the North American Dialing Plan (for voice, data, fax, etc.), the communication number always includes the area code and phone number using the format AAABBBCCCC, where AAA is the area code, BBB is the telephone number prefix, and CCCC is the telephone number (e.g. (534)224-2525 would be represented as 5342242525).\n- Required when the Member Employers contact information is provided to the sponsor. If not required by this implementation guide, do not send."
},
"member_employer_street_address_N3": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"member_employer_address_line_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Member Employer Address Line",
"type": "string"
},
"member_employer_address_line_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Member Employer Address Line",
"type": "string"
}
},
"required": ["member_employer_address_line_01"],
"title": "Member Employer Street Address",
"type": "object",
"x12-usage-notes": "- Required when the member's employer is not the sponsor and the employer address is provided to the sponsor by the member. If not required by this implementation guide, do not send."
},
"member_employer_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": ["member_employer_state_code_02"],
"type": "object",
"properties": {
"member_employer_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": ["member_employer_state_code_02"],
"type": "object",
"properties": {
"member_employer_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": ["country_code_04"]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"member_employer_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Member Employer City Name",
"type": "string"
},
"member_employer_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Member Employer State Code",
"type": "string"
},
"member_employer_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Member Employer Postal Zone or ZIP Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": ["member_employer_city_name_01"],
"title": "Member Employer City, State, ZIP Code",
"type": "object",
"x12-usage-notes": "- Required when the member's employer is not the sponsor and the employer address is provided to the sponsor by the member. If not required by this implementation guide, do not send."
}
},
"required": ["member_employer_NM1"],
"title": "Member Employer Loop",
"type": "object"
},
"maxItems": 3,
"minItems": 1,
"type": "array"
},
"member_school_NM1_loop": {
"items": {
"additionalProperties": false,
"properties": {
"member_school_NM1": {
"additionalProperties": false,
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["M8"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"M8": {
"description": "Educational Institution",
"code": "M8"
}
}
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["2"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"2": {
"description": "Non-Person Entity",
"code": "2"
}
}
},
"school_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "School Name",
"type": "string"
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02",
"school_name_03"
],
"title": "Member School",
"type": "object",
"x12-usage-notes": "- Required when the member is enrolled in school and the payer is required to be notified under the insurance contract between the sponsor and the payer. If not required by this implementation guide, do not send."
},
"member_school_commmunications_numbers_PER": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0506",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_05": [
"communication_number_06"
],
"communication_number_06": [
"communication_number_qualifier_05"
]
}
},
{
"x12-condition": "P0708",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_07": [
"communication_number_08"
],
"communication_number_08": [
"communication_number_qualifier_07"
]
}
}
],
"description": "To identify a person or office to whom administrative communications should be directed",
"properties": {
"contact_function_code_01": {
"description": "Code identifying the major duty or responsibility of the person or group named",
"enum": ["SK"],
"title": "Contact Function Code",
"type": "string",
"x12-codes": {
"SK": {
"description": "School Clerk",
"code": "SK"
}
}
},
"member_school_communications_contact_name_02": {
"description": "Free-form name",
"maxLength": 60,
"minLength": 1,
"title": "Member School Communications Contact Name",
"type": "string"
},
"communication_number_qualifier_03": {
"description": "Code identifying the type of communication number",
"enum": ["EM", "EX", "FX", "TE"],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"TE": {
"description": "Telephone",
"code": "TE"
}
}
},
"communication_number_04": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_05": {
"description": "Code identifying the type of communication number",
"enum": ["EM", "EX", "FX", "TE"],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"TE": {
"description": "Telephone",
"code": "TE"
}
}
},
"communication_number_06": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_07": {
"description": "Code identifying the type of communication number",
"enum": ["EM", "EX", "FX", "TE"],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"TE": {
"description": "Telephone",
"code": "TE"
}
}
},
"communication_number_08": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
}
},
"required": [
"contact_function_code_01",
"communication_number_qualifier_03",
"communication_number_04"
],
"title": "Member School Commmunications Numbers",
"type": "object",
"x12-usage-notes": "- When the communication number represents a telephone number in the United States and other countries using the North American Dialing Plan (for voice, data, fax, etc.), the communication number always includes the area code and phone number using the format AAABBBCCCC, where AAA is the area code, BBB is the telephone number prefix, and CCCC is the telephone number (e.g. (534)224-2525 would be represented as 5342242525).\n- Required when the Member School contact information is provided to the sponsor. If not required by this implementation guide, do not send."
},
"member_school_street_address_N3": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"school_address_line_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "School Address Line",
"type": "string"
},
"school_address_line_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "School Address Line",
"type": "string"
}
},
"required": ["school_address_line_01"],
"title": "Member School Street Address",
"type": "object",
"x12-usage-notes": "- Required when the member is enrolled in school and the school address is provided to the sponsor by the member. If not required by this implementation guide, do not send."
},
"member_school_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": ["member_school_state_code_02"],
"type": "object",
"properties": {
"member_school_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": ["member_school_state_code_02"],
"type": "object",
"properties": {
"member_school_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": ["country_code_04"]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"member_school_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Member School City Name",
"type": "string"
},
"member_school_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Member School State Code",
"type": "string"
},
"member_school_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Member School Postal Zone or ZIP Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": ["member_school_city_name_01"],
"title": "Member School City, State, ZIP Code",
"type": "object",
"x12-usage-notes": "- Required when the member is enrolled in school and the school address is provided to the sponsor by the member. If not required by this implementation guide, do not send."
}
},
"required": ["member_school_NM1"],
"title": "Member School Loop",
"type": "object"
},
"maxItems": 3,
"minItems": 1,
"type": "array"
},
"custodial_parent_NM1_loop": {
"additionalProperties": false,
"properties": {
"custodial_parent_NM1": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0809",
"type": "object",
"dependentRequired": {
"identification_code_qualifier_08": [
"custodial_parent_identifier_09"
],
"custodial_parent_identifier_09": [
"identification_code_qualifier_08"
]
}
}
],
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["S3"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"S3": {
"description": "Custodial Parent",
"code": "S3"
}
}
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["1"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"1": {
"description": "Person",
"code": "1"
}
}
},
"custodial_parent_last_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "Custodial Parent Last Name",
"type": "string"
},
"custodial_parent_first_name_04": {
"description": "Individual first name",
"maxLength": 35,
"minLength": 1,
"title": "Custodial Parent First Name",
"type": "string"
},
"custodial_parent_middle_name_05": {
"description": "Individual middle name or initial",
"maxLength": 25,
"minLength": 1,
"title": "Custodial Parent Middle Name",
"type": "string"
},
"custodial_parent_name_prefix_06": {
"description": "Prefix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Custodial Parent Name Prefix",
"type": "string"
},
"custodial_parent_name_suffix_07": {
"description": "Suffix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Custodial Parent Name Suffix",
"type": "string"
},
"identification_code_qualifier_08": {
"description": "Code designating the system/method of code structure used for Identification Code (67)",
"enum": ["34", "ZZ"],
"title": "Identification Code Qualifier",
"type": "string",
"x12-codes": {
"34": {
"description": "Social Security Number",
"code": "34",
"x12-usage-notes": "The social security number may not be used for any Federally administered programs such as Medicare or CHAMPUS/TRICARE."
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ",
"x12-usage-notes": "Value is required if National Individual Identifier is mandated for use. Otherwise, one of the other listed codes may be used."
}
}
},
"custodial_parent_identifier_09": {
"description": "Code identifying a party or other code",
"maxLength": 80,
"minLength": 2,
"title": "Custodial Parent Identifier",
"type": "string"
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02",
"custodial_parent_last_name_03",
"custodial_parent_first_name_04"
],
"title": "Custodial Parent",
"type": "object",
"x12-usage-notes": "- Required when the custodial parent of a minor dependent is someone other than the subscriber. If not required by this implementation guide, do not send.\n- Any other situation, (examples: Guardianship, Legal Indemnity, Power of Attorney, and/or Separation Agreements) would be handled under the Responsible Party NM1 segment."
},
"custodial_parent_communications_numbers_PER": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0506",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_05": [
"communication_number_06"
],
"communication_number_06": [
"communication_number_qualifier_05"
]
}
},
{
"x12-condition": "P0708",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_07": [
"communication_number_08"
],
"communication_number_08": [
"communication_number_qualifier_07"
]
}
}
],
"description": "To identify a person or office to whom administrative communications should be directed",
"properties": {
"contact_function_code_01": {
"description": "Code identifying the major duty or responsibility of the person or group named",
"enum": ["PQ"],
"title": "Contact Function Code",
"type": "string",
"x12-codes": {
"PQ": {
"description": "Parent or Guardian",
"code": "PQ"
}
}
},
"communication_number_qualifier_03": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_04": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_05": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_06": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_07": {
"description": "Code identifying the type of communication number",
"enum": ["AP", "BN", "CP", "EM", "EX", "HP", "TE", "WP"],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_08": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
}
},
"required": [
"contact_function_code_01",
"communication_number_qualifier_03",
"communication_number_04"
],
"title": "Custodial Parent Communications Numbers",
"type": "object",
"x12-usage-notes": "- When the communication number represents a telephone number in the United States and other countries using the North American Dialing Plan (for voice, data, fax, etc.), the communication number always includes the area code and phone number using the format AAABBBCCCC, where AAA is the area code, BBB is the telephone number prefix, and CCCC is the telephone number (e.g. (534)224-2525 would be represented as 5342242525).\n- Required when the Custodial Parent contact information is provided to the sponsor. If not required by this implementation guide, do not send."
},
"custodial_parent_street_address_N3": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"custodial_parent_address_line_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Custodial Parent Address Line",
"type": "string"
},
"custodial_parent_address_line_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Custodial Parent Address Line",
"type": "string"
}
},
"required": ["custodial_parent_address_line_01"],
"title": "Custodial Parent Street Address",
"type": "object",
"x12-usage-notes": "- Required when the custodial parent of a minor dependent is someone other than the subscriber and the information is provided to the sponsor. If not required by this implementation guide, do not send."
},
"custodial_parent_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": ["custodial_parent_state_code_02"],
"type": "object",
"properties": {
"custodial_parent_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": ["custodial_parent_state_code_02"],
"type": "object",
"properties": {
"custodial_parent_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": ["country_code_04"]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"custodial_parent_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Custodial Parent City Name",
"type": "string"
},
"custodial_parent_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Custodial Parent State Code",
"type": "string"
},
"custodial_parent_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Custodial Parent Postal Zone or ZIP Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": ["custodial_parent_city_name_01"],
"title": "Custodial Parent City, State, ZIP Code",
"type": "object",
"x12-usage-notes": "- Required when the custodial parent of a minor dependent is someone other than the subscriber and the information is provided to the sponsor. If not required by this implementation guide, do not send."
}
},
"required": ["custodial_parent_NM1"],
"title": "Custodial Parent Loop",
"type": "object"
},
"responsible_person_NM1_loop": {
"items": {
"additionalProperties": false,
"properties": {
"responsible_person_NM1": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0809",
"type": "object",
"dependentRequired": {
"identification_code_qualifier_08": [
"responsible_party_identifier_09"
],
"responsible_party_identifier_09": [
"identification_code_qualifier_08"
]
}
}
],
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": [
"6Y",
"9K",
"E1",
"EI",
"EXS",
"GB",
"GD",
"J6",
"LR",
"QD",
"S1",
"TZ",
"X4"
],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"6Y": {
"description": "Case Manager",
"code": "6Y"
},
"9K": {
"description": "Key Person",
"code": "9K"
},
"E1": {
"description": "Person or Other Entity Legally Responsible for a Child",
"code": "E1",
"x12-usage-notes": "Used to identify a legal indemnity situation.\n\r\nThis code is used when a Qualified Medical Child Support Order (QMSCO) is present."
},
"EI": {
"description": "Executor of Estate",
"code": "EI",
"x12-usage-notes": "This is used when the subscriber is deceased and the executor/responsible party is other than a surviving spouse."
},
"EXS": {
"description": "Ex-spouse",
"code": "EXS",
"x12-usage-notes": "This is used to identify a separated spouse under a separation agreement, or that the member is the divorced spouse and self responsible. This is NOT USED to identify the custodial parent for dependent children after a divorce."
},
"GB": {
"description": "Other Insured",
"code": "GB"
},
"GD": {
"description": "Guardian",
"code": "GD"
},
"J6": {
"description": "Power of Attorney",
"code": "J6"
},
"LR": {
"description": "Legal Representative",
"code": "LR"
},
"QD": {
"description": "Responsible Party",
"code": "QD"
},
"S1": {
"description": "Parent",
"code": "S1"
},
"TZ": {
"description": "Significant Other",
"code": "TZ"
},
"X4": {
"description": "Spouse",
"code": "X4"
}
}
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["1"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"1": {
"description": "Person",
"code": "1"
}
}
},
"responsible_party_last_or_organization_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "Responsible Party Last or Organization Name",
"type": "string"
},
"responsible_party_first_name_04": {
"description": "Individual first name",
"maxLength": 35,
"minLength": 1,
"title": "Responsible Party First Name",
"type": "string"
},
"responsible_party_middle_name_05": {
"description": "Individual middle name or initial",
"maxLength": 25,
"minLength": 1,
"title": "Responsible Party Middle Name",
"type": "string"
},
"responsible_party_name_prefix_06": {
"description": "Prefix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Responsible Party Name Prefix",
"type": "string"
},
"responsible_party_suffix_name_07": {
"description": "Suffix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Responsible Party Suffix Name",
"type": "string"
},
"identification_code_qualifier_08": {
"description": "Code designating the system/method of code structure used for Identification Code (67)",
"enum": ["34", "ZZ"],
"title": "Identification Code Qualifier",
"type": "string",
"x12-codes": {
"34": {
"description": "Social Security Number",
"code": "34",
"x12-usage-notes": "The social security number may not be used for any Federally administered programs such as Medicare or CHAMPUS/TRICARE."
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ",
"x12-usage-notes": "Value is required if National Individual Identifier is mandated for use. Otherwise, one of the other listed codes may be used."
}
}
},
"responsible_party_identifier_09": {
"description": "Code identifying a party or other code",
"maxLength": 80,
"minLength": 2,
"title": "Responsible Party Identifier",
"type": "string"
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02",
"responsible_party_last_or_organization_name_03"
],
"title": "Responsible Person",
"type": "object",
"x12-usage-notes": "- Required to identify the person(s), other than the subscriber, who are responsible for the member. If not required by this implementation guide, do not send."
},
"responsible_person_communications_numbers_PER": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0506",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_05": [
"communication_number_06"
],
"communication_number_06": [
"communication_number_qualifier_05"
]
}
},
{
"x12-condition": "P0708",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_07": [
"communication_number_08"
],
"communication_number_08": [
"communication_number_qualifier_07"
]
}
}
],
"description": "To identify a person or office to whom administrative communications should be directed",
"properties": {
"contact_function_code_01": {
"description": "Code identifying the major duty or responsibility of the person or group named",
"enum": ["RP"],
"title": "Contact Function Code",
"type": "string",
"x12-codes": {
"RP": {
"description": "Responsible Person",
"code": "RP"
}
}
},
"communication_number_qualifier_03": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_04": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_05": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_06": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_07": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_08": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
}
},
"required": [
"contact_function_code_01",
"communication_number_qualifier_03",
"communication_number_04"
],
"title": "Responsible Person Communications Numbers",
"type": "object",
"x12-usage-notes": "- When the communication number represents a telephone number in the United States and other countries using the North American Dialing Plan (for voice, data, fax, etc.), the communication number always includes the area code and phone number using the format AAABBBCCCC, where AAA is the area code, BBB is the telephone number prefix, and CCCC is the telephone number (e.g. (534)224-2525 would be represented as 5342242525).\n- Required when the Responsible Person contact information is provided to the sponsor. If not required by this implementation guide, do not send."
},
"responsible_person_street_address_N3": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"responsible_party_address_line_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Responsible Party Address Line",
"type": "string"
},
"responsible_party_address_line_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Responsible Party Address Line",
"type": "string"
}
},
"required": ["responsible_party_address_line_01"],
"title": "Responsible Person Street Address",
"type": "object",
"x12-usage-notes": "- Required when there is a person other than the subscriber who is responsible for the member and the responsible person's address is provided to the sponsor. If not required by this implementation guide, do not send."
},
"responsible_person_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": ["responsible_person_state_code_02"],
"type": "object",
"properties": {
"responsible_person_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": [
"responsible_person_state_code_02"
],
"type": "object",
"properties": {
"responsible_person_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": ["country_code_04"]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"responsible_person_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Responsible Person City Name",
"type": "string"
},
"responsible_person_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Responsible Person State Code",
"type": "string"
},
"responsible_person_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Responsible Person Postal Zone or ZIP Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": ["responsible_person_city_name_01"],
"title": "Responsible Person City, State, ZIP Code",
"type": "object",
"x12-usage-notes": "- Required when there is a person other than the subscriber who is responsible for the member and the responsible person's address is provided to the sponsor. If not required by this implementation guide, do not send."
}
},
"required": ["responsible_person_NM1"],
"title": "Responsible Person Loop",
"type": "object"
},
"maxItems": 13,
"minItems": 1,
"type": "array"
},
"drop_off_location_NM1_loop": {
"additionalProperties": false,
"properties": {
"drop_off_location_NM1": {
"additionalProperties": false,
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["45"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"45": {
"description": "Drop-off Location",
"code": "45"
}
}
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["1"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"1": {
"description": "Person",
"code": "1"
}
}
},
"name_last_or_organization_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "Name Last or Organization Name",
"type": "string"
},
"name_first_04": {
"description": "Individual first name",
"maxLength": 35,
"minLength": 1,
"title": "Name First",
"type": "string"
},
"name_middle_05": {
"description": "Individual middle name or initial",
"maxLength": 25,
"minLength": 1,
"title": "Name Middle",
"type": "string"
},
"name_prefix_06": {
"description": "Prefix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Name Prefix",
"type": "string"
},
"name_suffix_07": {
"description": "Suffix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Name Suffix",
"type": "string"
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02"
],
"title": "Drop Off Location",
"type": "object",
"x12-usage-notes": "- Required when member has requested shipments to be sent to an address other then their residence or mailing. If not required by this implementation guide, do not send."
},
"drop_off_location_street_address_N3": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"drop_off_location_address_line_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Drop Off Location Address Line",
"type": "string"
},
"drop_off_location_address_line_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Drop Off Location Address Line",
"type": "string"
}
},
"required": ["drop_off_location_address_line_01"],
"title": "Drop Off Location Street Address",
"type": "object",
"x12-usage-notes": "- Required when member has requested shipments to be sent to an address other than their residence or mailing. If not required by this implementation guide, do not send."
},
"drop_off_location_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": ["drop_off_location_state_code_02"],
"type": "object",
"properties": {
"drop_off_location_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": ["drop_off_location_state_code_02"],
"type": "object",
"properties": {
"drop_off_location_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": ["country_code_04"]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"drop_off_location_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Drop Off Location City Name",
"type": "string"
},
"drop_off_location_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Drop Off Location State Code",
"type": "string"
},
"drop_off_location_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Drop Off Location Postal Zone or ZIP Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": ["drop_off_location_city_name_01"],
"title": "Drop Off Location City, State, ZIP Code",
"type": "object",
"x12-usage-notes": "- Required when member has requested shipments to be sent to an address other than their residence or mailing. If not required by this implementation guide, do not send."
}
},
"required": ["drop_off_location_NM1"],
"title": "Drop Off Location Loop",
"type": "object"
},
"disability_information_DSB_loop": {
"items": {
"additionalProperties": false,
"properties": {
"disability_information_DSB": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0708",
"type": "object",
"dependentRequired": {
"product_or_service_id_qualifier_07": [
"diagnosis_code_08"
],
"diagnosis_code_08": [
"product_or_service_id_qualifier_07"
]
}
}
],
"description": "To supply disability information",
"properties": {
"disability_type_code_01": {
"description": "Code identifying the disability status of the individual",
"enum": ["1", "2", "3", "4"],
"title": "Disability Type Code",
"type": "string",
"x12-codes": {
"1": {
"description": "Short Term Disability",
"code": "1"
},
"2": {
"description": "Long Term Disability",
"code": "2"
},
"3": {
"description": "Permanent or Total Disability",
"code": "3"
},
"4": {
"description": "No Disability",
"code": "4"
}
}
},
"product_or_service_id_qualifier_07": {
"description": "Code identifying the type/source of the descriptive number used in Product/Service ID (234)",
"enum": ["DX", "ZZ"],
"title": "Product or Service ID Qualifier",
"type": "string",
"x12-codes": {
"DX": {
"description": "International Classification of Diseases, 9th Revision, Clinical Modification (ICD-9-CM) - Diagnosis",
"code": "DX"
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ",
"x12-usage-notes": "To be used for the International Classification of Diseases, 10th Revision, Clinical Modification (ICD-10-CM) - Diagnosis.\n\r\nCODE SOURCE: 897 International Classification of Diseases, 10th Revision, Clinical Modification (ICD-10-CM)"
}
}
},
"diagnosis_code_08": {
"description": "Code value for describing a medical condition or procedure\n\n- DSB08 is the functional status code for the disability.",
"maxLength": 15,
"minLength": 1,
"title": "Diagnosis Code",
"type": "string"
}
},
"required": ["disability_type_code_01"],
"title": "Disability Information",
"type": "object",
"x12-usage-notes": "- Required when enrolling a disabled member or when disability information about an existing member is added or changed. If not required by this implementation guide, do not send."
},
"disability_eligibility_dates_DTP": {
"items": {
"additionalProperties": false,
"description": "To specify any or all of a date, a time, or a time period",
"properties": {
"date_time_qualifier_01": {
"description": "Code specifying type of date or time, or both date and time",
"enum": ["360", "361"],
"title": "Date Time Qualifier",
"type": "string",
"x12-codes": {
"360": {
"description": "Initial Disability Period Start",
"code": "360"
},
"361": {
"description": "Initial Disability Period End",
"code": "361"
}
}
},
"date_time_period_format_qualifier_02": {
"description": "Code indicating the date format, time format, or date and time format\n\n- DTP02 is the date or time or period format that will appear in DTP03.",
"enum": ["D8"],
"title": "Date Time Period Format Qualifier",
"type": "string",
"x12-codes": {
"D8": {
"description": "Date Expressed in Format CCYYMMDD",
"code": "D8"
}
}
},
"disability_eligibility_date_03": {
"description": "Expression of a date, a time, or range of dates, times or dates and times",
"maxLength": 35,
"minLength": 1,
"title": "Disability Eligibility Date",
"type": "string"
}
},
"required": [
"date_time_qualifier_01",
"date_time_period_format_qualifier_02",
"disability_eligibility_date_03"
],
"title": "Disability Eligibility Dates",
"type": "object",
"x12-usage-notes": "- This segment is used to send the first and last date of disability.\n- Required when enrolling a disabled member or when disability dates change for an existing member, and the disability dates are known by the sponsor. If not required by this implementation guide, do not send."
},
"maxItems": 2,
"minItems": 1,
"type": "array"
}
},
"required": ["disability_information_DSB"],
"title": "Disability Information Loop",
"type": "object"
},
"minItems": 1,
"type": "array"
},
"health_coverage_HD_loop": {
"items": {
"additionalProperties": false,
"properties": {
"health_coverage_HD": {
"additionalProperties": false,
"description": "To provide information on health coverage",
"properties": {
"maintenance_type_code_01": {
"description": "Code identifying the specific type of item maintenance",
"enum": [
"001",
"002",
"021",
"024",
"025",
"026",
"030",
"032"
],
"title": "Maintenance Type Code",
"type": "string",
"x12-codes": {
"001": {
"description": "Change",
"code": "001"
},
"002": {
"description": "Delete",
"code": "002",
"x12-usage-notes": "Use this code for deleting an incorrect coverage record."
},
"021": {
"description": "Addition",
"code": "021"
},
"024": {
"description": "Cancellation or Termination",
"code": "024",
"x12-usage-notes": "Use this code for cancelling/terminating a coverage."
},
"025": {
"description": "Reinstatement",
"code": "025"
},
"026": {
"description": "Correction",
"code": "026",
"x12-usage-notes": "This code is used to correct an incorrect record."
},
"030": {
"description": "Audit or Compare",
"code": "030"
},
"032": {
"description": "Employee Information Not Applicable",
"code": "032",
"x12-usage-notes": "Certain situations, such as military duty and CHAMPUS/TRICARE, classify the subscriber as ineligible for coverage or benefits. However, dependents of the subscribers are still eligible for coverage or benefits under the subscriber. Subscriber identifying elements are needed to accurately identify dependents."
}
},
"x12-usage-notes": "- Required to identify the specific type of item maintenance."
},
"insurance_line_code_03": {
"description": "Code identifying a group of insurance products",
"enum": [
"AG",
"AH",
"AJ",
"AK",
"DCP",
"DEN",
"EPO",
"FAC",
"HE",
"HLT",
"HMO",
"LTC",
"LTD",
"MM",
"MOD",
"PDG",
"POS",
"PPO",
"PRA",
"STD",
"UR",
"VIS"
],
"title": "Insurance Line Code",
"type": "string",
"x12-codes": {
"AG": {
"description": "Preventative Care/Wellness",
"code": "AG"
},
"AH": {
"description": "24 Hour Care",
"code": "AH"
},
"AJ": {
"description": "Medicare Risk",
"code": "AJ"
},
"AK": {
"description": "Mental Health",
"code": "AK"
},
"DCP": {
"description": "Dental Capitation",
"code": "DCP",
"x12-usage-notes": "This identifies a dental managed care organization (DMO)."
},
"DEN": {
"description": "Dental",
"code": "DEN"
},
"EPO": {
"description": "Exclusive Provider Organization",
"code": "EPO"
},
"FAC": {
"description": "Facility",
"code": "FAC"
},
"HE": {
"description": "Hearing",
"code": "HE"
},
"HLT": {
"description": "Health",
"code": "HLT",
"x12-usage-notes": "Includes both hospital and professional coverage."
},
"HMO": {
"description": "Health Maintenance Organization",
"code": "HMO"
},
"LTC": {
"description": "Long-Term Care",
"code": "LTC"
},
"LTD": {
"description": "Long-Term Disability",
"code": "LTD"
},
"MM": {
"description": "Major Medical",
"code": "MM"
},
"MOD": {
"description": "Mail Order Drug",
"code": "MOD"
},
"PDG": {
"description": "Prescription Drug",
"code": "PDG"
},
"POS": {
"description": "Point of Service",
"code": "POS"
},
"PPO": {
"description": "Preferred Provider Organization",
"code": "PPO"
},
"PRA": {
"description": "Practitioners",
"code": "PRA"
},
"STD": {
"description": "Short-Term Disability",
"code": "STD"
},
"UR": {
"description": "Utilization Review",
"code": "UR"
},
"VIS": {
"description": "Vision",
"code": "VIS"
}
}
},
"plan_coverage_description_04": {
"description": "A description or number that identifies the plan or coverage",
"maxLength": 50,
"minLength": 1,
"title": "Plan Coverage Description",
"type": "string"
},
"coverage_level_code_05": {
"description": "Code indicating the level of coverage being provided for this insured",
"enum": [
"CHD",
"DEP",
"E1D",
"E2D",
"E3D",
"E5D",
"E6D",
"E7D",
"E8D",
"E9D",
"ECH",
"EMP",
"ESP",
"FAM",
"IND",
"SPC",
"SPO",
"TWO"
],
"title": "Coverage Level Code",
"type": "string",
"x12-codes": {
"CHD": {
"description": "Children Only",
"code": "CHD"
},
"DEP": {
"description": "Dependents Only",
"code": "DEP"
},
"E1D": {
"description": "Employee and One Dependent",
"code": "E1D",
"x12-usage-notes": "For this code, the dependent is a non-spouse dependent. This code is not used for identification of Employee and Spouse. See code ESP."
},
"E2D": {
"description": "Employee and Two Dependents",
"code": "E2D"
},
"E3D": {
"description": "Employee and Three Dependents",
"code": "E3D"
},
"E5D": {
"description": "Employee and One or More Dependents",
"code": "E5D"
},
"E6D": {
"description": "Employee and Two or More Dependents",
"code": "E6D"
},
"E7D": {
"description": "Employee and Three or More Dependents",
"code": "E7D"
},
"E8D": {
"description": "Employee and Four or More Dependents",
"code": "E8D"
},
"E9D": {
"description": "Employee and Five or More Dependents",
"code": "E9D"
},
"ECH": {
"description": "Employee and Children",
"code": "ECH"
},
"EMP": {
"description": "Employee Only",
"code": "EMP"
},
"ESP": {
"description": "Employee and Spouse",
"code": "ESP"
},
"FAM": {
"description": "Family",
"code": "FAM"
},
"IND": {
"description": "Individual",
"code": "IND"
},
"SPC": {
"description": "Spouse and Children",
"code": "SPC"
},
"SPO": {
"description": "Spouse Only",
"code": "SPO"
},
"TWO": {
"description": "Two Party",
"code": "TWO"
}
},
"x12-usage-notes": "- See section 1.4.6, Coverage Levels and Dependents, for additional information."
},
"late_enrollment_indicator_09": {
"description": "Code indicating a Yes or No condition or response\n\n- HD09 is a late enrollee indicator. A \"Y\" value indicates the insured is a late enrollee, which can result in a reduction of benefits; an \"N\" value indicates the insured is a regular enrollee.",
"enum": ["N", "Y"],
"title": "Late Enrollment Indicator",
"type": "string",
"x12-codes": {
"N": {
"description": "No",
"code": "N"
},
"Y": {
"description": "Yes",
"code": "Y"
}
}
}
},
"required": [
"maintenance_type_code_01",
"insurance_line_code_03"
],
"title": "Health Coverage",
"type": "object",
"x12-usage-notes": "- Required when enrolling a new member or when adding, updating, removing coverage or auditing an existing member. If not required by this implementation guide, do not send.\n- Refer to section 1.4.4 \"Termination\" for additional information relative to removing a member's coverage."
},
"health_coverage_dates_DTP": {
"items": {
"additionalProperties": false,
"description": "To specify any or all of a date, a time, or a time period",
"properties": {
"date_time_qualifier_01": {
"description": "Code specifying type of date or time, or both date and time",
"enum": [
"300",
"303",
"343",
"348",
"349",
"543",
"695"
],
"title": "Date Time Qualifier",
"type": "string",
"x12-codes": {
"300": {
"description": "Enrollment Signature Date",
"code": "300"
},
"303": {
"description": "Maintenance Effective",
"code": "303",
"x12-usage-notes": "This is the effective date of a change where a member's coverage is not being added or removed."
},
"343": {
"description": "Premium Paid to Date End",
"code": "343"
},
"348": {
"description": "Benefit Begin",
"code": "348",
"x12-usage-notes": "This is the effective date of coverage. This code must always be sent when adding or reinstating coverage."
},
"349": {
"description": "Benefit End",
"code": "349",
"x12-usage-notes": "The termination date represents the last date of coverage in which claims will be paid for the individual being terminated. For example, if a date of 02/28/2001 is passed then claims for this individual will be paid through 11:59 p.m. on 2/28/01."
},
"543": {
"description": "Last Premium Paid Date",
"code": "543"
},
"695": {
"description": "Previous Period",
"code": "695",
"x12-usage-notes": "This value is only to be used when reporting Previous Coverage Months."
}
}
},
"date_time_period_format_qualifier_02": {
"description": "Code indicating the date format, time format, or date and time format\n\n- DTP02 is the date or time or period format that will appear in DTP03.",
"enum": ["D8", "RD8"],
"title": "Date Time Period Format Qualifier",
"type": "string",
"x12-codes": {
"D8": {
"description": "Date Expressed in Format CCYYMMDD",
"code": "D8"
},
"RD8": {
"description": "Range of Dates Expressed in Format CCYYMMDD-CCYYMMDD",
"code": "RD8",
"x12-usage-notes": "This value is only to be used when reporting Previous Coverage Months."
}
}
},
"coverage_period_03": {
"description": "Expression of a date, a time, or range of dates, times or dates and times",
"maxLength": 35,
"minLength": 1,
"title": "Coverage Period",
"type": "string"
}
},
"required": [
"date_time_qualifier_01",
"date_time_period_format_qualifier_02",
"coverage_period_03"
],
"title": "Health Coverage Dates",
"type": "object",
"x12-usage-notes": ""
},
"maxItems": 6,
"minItems": 1,
"type": "array"
},
"health_coverage_policy_AMT": {
"items": {
"additionalProperties": false,
"description": "To indicate the total monetary amount",
"properties": {
"amount_qualifier_code_01": {
"description": "Code to qualify amount",
"enum": ["B9", "C1", "D2", "EBA", "FK", "P3", "R"],
"title": "Amount Qualifier Code",
"type": "string",
"x12-codes": {
"B9": {
"description": "Co-insurance - Actual",
"code": "B9",
"x12-usage-notes": "This will contain any co-insurance selection amount. The option of adjusting this amount to produce the actual co-insurance can be defined in the insurance contract."
},
"C1": {
"description": "Co-Payment Amount",
"code": "C1"
},
"D2": {
"description": "Deductible Amount",
"code": "D2"
},
"EBA": {
"description": "Expected Expenditure Amount",
"code": "EBA"
},
"FK": {
"description": "Other Unlisted Amount",
"code": "FK"
},
"P3": {
"description": "Premium Amount",
"code": "P3"
},
"R": {
"description": "Spend Down",
"code": "R"
}
}
},
"contract_amount_02": {
"description": "Monetary amount",
"title": "Contract Amount",
"type": "number",
"x12-max-length": 15
}
},
"required": [
"amount_qualifier_code_01",
"contract_amount_02"
],
"title": "Health Coverage Policy",
"type": "object",
"x12-usage-notes": "- Required when such transmission is required under the insurance contract between the sponsor and the payer. If not required by this implementation guide, do not send."
},
"maxItems": 9,
"minItems": 1,
"type": "array"
},
"health_coverage_policy_number_REF": {
"items": {
"additionalProperties": false,
"description": "To specify identifying information",
"properties": {
"reference_identification_qualifier_01": {
"description": "Code qualifying the Reference Identification",
"enum": [
"1L",
"9V",
"17",
"CE",
"E8",
"M7",
"PID",
"RB",
"X9",
"XM",
"XX1",
"XX2",
"ZX",
"ZZ"
],
"title": "Reference Identification Qualifier",
"type": "string",
"x12-codes": {
"17": {
"description": "Client Reporting Category",
"code": "17"
},
"1L": {
"description": "Group or Policy Number",
"code": "1L",
"x12-usage-notes": "Required when a group number that applies to this individual's participation in the coverage passed in this HD loop is required by the terms of the contract between the sponsor (sender) and payer (receiver); if not required may be sent at the sender's discretion."
},
"9V": {
"description": "Payment Category",
"code": "9V"
},
"CE": {
"description": "Class of Contract Code",
"code": "CE"
},
"E8": {
"description": "Service Contract (Coverage) Number",
"code": "E8"
},
"M7": {
"description": "Medical Assistance Category",
"code": "M7"
},
"PID": {
"description": "Program Identification Number",
"code": "PID"
},
"RB": {
"description": "Rate code number",
"code": "RB"
},
"X9": {
"description": "Internal Control Number",
"code": "X9"
},
"XM": {
"description": "Issuer Number",
"code": "XM"
},
"XX1": {
"description": "Special Program Code",
"code": "XX1"
},
"XX2": {
"description": "Service Area Code",
"code": "XX2"
},
"ZX": {
"description": "County Code",
"code": "ZX"
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ",
"x12-usage-notes": "Use this code for the Payment Plan Type Code (Annual or Quarterly) until a standard code is assigned."
}
}
},
"member_group_or_policy_number_02": {
"description": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier",
"maxLength": 50,
"minLength": 1,
"title": "Member Group or Policy Number",
"type": "string"
}
},
"required": [
"reference_identification_qualifier_01",
"member_group_or_policy_number_02"
],
"title": "Health Coverage Policy Number",
"type": "object",
"x12-usage-notes": "- Required when such transmission is required under the Trading Partner Agreement between the sponsor and the payer. If not required by this implementation guide, do not send."
},
"maxItems": 14,
"minItems": 1,
"type": "array"
},
"prior_coverage_months_REF": {
"additionalProperties": false,
"description": "To specify identifying information",
"properties": {
"reference_identification_qualifier_01": {
"description": "Code qualifying the Reference Identification",
"enum": ["QQ"],
"title": "Reference Identification Qualifier",
"type": "string",
"x12-codes": {
"QQ": {
"description": "Unit Number",
"code": "QQ",
"x12-usage-notes": "This code is used in this implementation guide to indicate that the value in REF02 is the response required under the portability provisions of HIPAA."
}
}
},
"prior_coverage_month_count_02": {
"description": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier",
"maxLength": 50,
"minLength": 1,
"title": "Prior Coverage Month Count",
"type": "string",
"x12-usage-notes": "- Indicator identifying the number of prior months insurance coverage that may apply under the portability provisions of the Health Insurance Portability and Accountability Act.\n- This field will contain the number of months of prior health insurance coverage that meets the portability requirements of the HIPAA certification requirements. To be sent on new enrollments when available."
}
},
"required": [
"reference_identification_qualifier_01",
"prior_coverage_month_count_02"
],
"title": "Prior Coverage Months",
"type": "object",
"x12-usage-notes": "- Required when the portability provisions of the Health Insurance Portability and Accountability Act require reporting of the number of months of prior health coverage that meet the certification requirements of the Act."
},
"identification_card_IDC": {
"items": {
"additionalProperties": false,
"description": "To provide notification to produce replacement identification card(s)",
"properties": {
"plan_coverage_description_01": {
"description": "A description or number that identifies the plan or coverage",
"maxLength": 50,
"minLength": 1,
"title": "Plan Coverage Description",
"type": "string",
"x12-usage-notes": "- If no additional information is needed, this element will be sent as a single zero."
},
"identification_card_type_code_02": {
"description": "Code identifying the type of identification card",
"enum": ["D", "H", "P"],
"title": "Identification Card Type Code",
"type": "string",
"x12-codes": {
"D": {
"description": "Dental Insurance",
"code": "D"
},
"H": {
"description": "Health Insurance",
"code": "H"
},
"P": {
"description": "Prescription Drug Service Drug Insurance",
"code": "P"
}
},
"x12-usage-notes": "- This code is used to identify that the card issued will be specific to the coverage identified in the related HD segment."
},
"identification_card_count_03": {
"description": "Numeric value of quantity\n\n- IDC03 is the number of cards being requested.",
"title": "Identification Card Count",
"type": "number",
"x12-usage-notes": "- Only non-negative integer values are to be sent.",
"x12-max-length": 15
},
"action_code_04": {
"description": "Code indicating type of action\n\n- IDC04 is the reason for the card being requested, i.e., add or a change.",
"enum": ["1", "2", "RX"],
"title": "Action Code",
"type": "string",
"x12-codes": {
"1": {
"description": "Add",
"code": "1"
},
"2": {
"description": "Change (Update)",
"code": "2"
},
"RX": {
"description": "Replace",
"code": "RX",
"x12-usage-notes": "Use when requesting replacement cards with no change to data."
}
}
}
},
"required": [
"plan_coverage_description_01",
"identification_card_type_code_02"
],
"title": "Identification Card",
"type": "object",
"x12-usage-notes": "- Required when requesting the production of an identification card as the result of an enrollment add, change, or statement. If not required by this implementation guide, do not send.\n- An enrollment statement refers to a situation where no change is being made to the enrollment except to request a replacement ID card."
},
"maxItems": 3,
"minItems": 1,
"type": "array"
},
"provider_information_LX_loop": {
"items": {
"additionalProperties": false,
"properties": {
"provider_information_LX": {
"additionalProperties": false,
"description": "To reference a line number in a transaction set",
"properties": {
"assigned_number_01": {
"description": "Number assigned for differentiation within a transaction set",
"title": "Assigned Number",
"type": "integer",
"x12-usage-notes": "- This is a sequential number representing the number of loops for this insured person. Begin with 1 for each insured person.",
"x12-max-length": 6,
"minimum": -999999,
"maximum": 999999
}
},
"required": ["assigned_number_01"],
"title": "Provider Information",
"type": "object",
"x12-usage-notes": "- Required to provide information about the primary care or capitated physicians and pharmacies chosen by the enrollee in a managed care plan when that selection is made through the sponsor. If not required by this implementation guide, do not send.\n- Use one iteration of the loop to identify each applicable health care service provider.\n- The primary care provider effective date is defaulted to the effective date of the product identified in the DTP segment of the 2300 loop. When an enrollee switches from one primary care provider to another through the sponsor, the new provider must be listed with the effective date of change."
},
"provider_name_NM1": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0809",
"type": "object",
"dependentRequired": {
"identification_code_qualifier_08": [
"provider_identifier_09"
],
"provider_identifier_09": [
"identification_code_qualifier_08"
]
}
}
],
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": [
"1X",
"3D",
"80",
"FA",
"OD",
"P3",
"QA",
"QN",
"Y2"
],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"80": {
"description": "Hospital",
"code": "80"
},
"1X": {
"description": "Laboratory",
"code": "1X"
},
"3D": {
"description": "Obstetrics and Gynecology Facility",
"code": "3D"
},
"FA": {
"description": "Facility",
"code": "FA"
},
"OD": {
"description": "Doctor of Optometry",
"code": "OD"
},
"P3": {
"description": "Primary Care Provider",
"code": "P3"
},
"QA": {
"description": "Pharmacy",
"code": "QA"
},
"QN": {
"description": "Dentist",
"code": "QN"
},
"Y2": {
"description": "Managed Care Organization",
"code": "Y2"
}
}
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["1", "2"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"1": {
"description": "Person",
"code": "1"
},
"2": {
"description": "Non-Person Entity",
"code": "2"
}
}
},
"provider_last_or_organization_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "Provider Last or Organization Name",
"type": "string"
},
"provider_first_name_04": {
"description": "Individual first name",
"maxLength": 35,
"minLength": 1,
"title": "Provider First Name",
"type": "string"
},
"provider_middle_name_05": {
"description": "Individual middle name or initial",
"maxLength": 25,
"minLength": 1,
"title": "Provider Middle Name",
"type": "string"
},
"provider_name_prefix_06": {
"description": "Prefix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Provider Name Prefix",
"type": "string"
},
"provider_name_suffix_07": {
"description": "Suffix to individual name",
"maxLength": 10,
"minLength": 1,
"title": "Provider Name Suffix",
"type": "string"
},
"identification_code_qualifier_08": {
"description": "Code designating the system/method of code structure used for Identification Code (67)",
"enum": ["34", "FI", "SV", "XX"],
"title": "Identification Code Qualifier",
"type": "string",
"x12-codes": {
"34": {
"description": "Social Security Number",
"code": "34",
"x12-usage-notes": "The social security number may not be used for any Federally administered programs such as Medicare or CHAMPUS/TRICARE."
},
"FI": {
"description": "Federal Taxpayer's Identification Number",
"code": "FI"
},
"SV": {
"description": "Service Provider Number",
"code": "SV",
"x12-usage-notes": "This is a number assigned by the payer used to identify a provider."
},
"XX": {
"description": "Centers for Medicare and Medicaid Services National Provider Identifier",
"code": "XX"
}
}
},
"provider_identifier_09": {
"description": "Code identifying a party or other code",
"maxLength": 80,
"minLength": 2,
"title": "Provider Identifier",
"type": "string"
},
"entity_relationship_code_10": {
"description": "Code describing entity relationship\n\n- NM110 and NM111 further define the type of entity in NM101.",
"enum": ["25", "26", "72"],
"title": "Entity Relationship Code",
"type": "string",
"x12-codes": {
"25": {
"description": "Established Patient",
"code": "25"
},
"26": {
"description": "Not Established Patient",
"code": "26"
},
"72": {
"description": "Unknown",
"code": "72"
}
},
"x12-usage-notes": "- This element indicates whether or not the member is an existing patient of the provider."
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02",
"entity_relationship_code_10"
],
"title": "Provider Name",
"type": "object",
"x12-usage-notes": "- The National Provider ID must be passed in NM109. Until that ID is available, the Federal Taxpayer's Identification Number or another identification number that is necessary to identify the entity must be sent if available. If the identification number is not available then the Provider's Name must be passed using elements NM103 through NM107 as outlined in segment note 2."
},
"provider_address_N3": {
"items": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"provider_address_line_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Provider Address Line",
"type": "string"
},
"provider_address_line_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Provider Address Line",
"type": "string"
}
},
"required": ["provider_address_line_01"],
"title": "Provider Address",
"type": "object",
"x12-usage-notes": "- Required when the location of the named provider needs to be reported. If not required by this implementation guide, do not send."
},
"maxItems": 2,
"minItems": 1,
"type": "array"
},
"provider_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": ["provider_state_code_02"],
"type": "object",
"properties": {
"provider_state_code_02": true
}
},
{
"required": ["country_subdivision_code_07"],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": ["provider_state_code_02"],
"type": "object",
"properties": {
"provider_state_code_02": true
}
},
{
"required": [
"country_subdivision_code_07"
],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": ["country_code_04"]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"provider_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Provider City Name",
"type": "string"
},
"provider_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Provider State Code",
"type": "string"
},
"provider_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Provider Postal Zone or ZIP Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": ["provider_city_name_01"],
"title": "Provider City, State, ZIP Code",
"type": "object",
"x12-usage-notes": "- Required when the location of the named provider needs to be reported. If not required by this implementation guide, do not send."
},
"provider_communications_numbers_PER": {
"items": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0506",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_05": [
"communication_number_06"
],
"communication_number_06": [
"communication_number_qualifier_05"
]
}
},
{
"x12-condition": "P0708",
"type": "object",
"dependentRequired": {
"communication_number_qualifier_07": [
"communication_number_08"
],
"communication_number_08": [
"communication_number_qualifier_07"
]
}
}
],
"description": "To identify a person or office to whom administrative communications should be directed",
"properties": {
"contact_function_code_01": {
"description": "Code identifying the major duty or responsibility of the person or group named",
"enum": ["IC"],
"title": "Contact Function Code",
"type": "string",
"x12-codes": {
"IC": {
"description": "Information Contact",
"code": "IC"
}
}
},
"communication_number_qualifier_03": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_04": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_05": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_06": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
},
"communication_number_qualifier_07": {
"description": "Code identifying the type of communication number",
"enum": [
"AP",
"BN",
"CP",
"EM",
"EX",
"FX",
"HP",
"TE",
"WP"
],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"AP": {
"description": "Alternate Telephone",
"code": "AP"
},
"BN": {
"description": "Beeper Number",
"code": "BN"
},
"CP": {
"description": "Cellular Phone",
"code": "CP"
},
"EM": {
"description": "Electronic Mail",
"code": "EM"
},
"EX": {
"description": "Telephone Extension",
"code": "EX"
},
"FX": {
"description": "Facsimile",
"code": "FX"
},
"HP": {
"description": "Home Phone Number",
"code": "HP"
},
"TE": {
"description": "Telephone",
"code": "TE"
},
"WP": {
"description": "Work Phone Number",
"code": "WP"
}
}
},
"communication_number_08": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
}
},
"required": [
"contact_function_code_01",
"communication_number_qualifier_03",
"communication_number_04"
],
"title": "Provider Communications Numbers",
"type": "object",
"x12-usage-notes": "- When the communication number represents a telephone number in the United States and other countries using the North American Dialing Plan (for voice, data, fax, etc.), the communication number always includes the area code and phone number using the format AAABBBCCCC, where AAA is the area code, BBB is the telephone number prefix, and CCCC is the telephone number (e.g. (534)224-2525 would be represented as 5342242525).\n- Required when the Provider contact information is provided to the sponsor. If not required by this implementation guide, do not send."
},
"maxItems": 2,
"minItems": 1,
"type": "array"
},
"provider_change_reason_PLA": {
"additionalProperties": false,
"description": "To indicate action to be taken for the location specified and to qualify the location specified",
"properties": {
"action_code_01": {
"description": "Code indicating type of action",
"enum": ["2"],
"title": "Action Code",
"type": "string",
"x12-codes": {
"2": {
"description": "Change (Update)",
"code": "2"
}
}
},
"entity_identifier_code_02": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["1P"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"1P": {
"description": "Provider",
"code": "1P"
}
}
},
"provider_effective_date_03": {
"description": "Date expressed as CCYYMMDD where CC represents the first two digits of the calendar year\n\n- PLA03 is the effective date for the action identified in PLA01.",
"format": "date",
"title": "Provider Effective Date",
"type": "string",
"x12-usage-notes": "- This is the effective date of the change of PCP."
},
"maintenance_reason_code_05": {
"description": "Code identifying the reason for the maintenance change",
"enum": [
"14",
"22",
"46",
"AA",
"AB",
"AC",
"AD",
"AE",
"AF",
"AG",
"AH",
"AI",
"AJ"
],
"title": "Maintenance Reason Code",
"type": "string",
"x12-codes": {
"14": {
"description": "Voluntary Withdrawal",
"code": "14"
},
"22": {
"description": "Plan Change",
"code": "22"
},
"46": {
"description": "Current Customer Information File in Error",
"code": "46"
},
"AA": {
"description": "Dissatisfaction with Office Staff",
"code": "AA"
},
"AB": {
"description": "Dissatisfaction with Medical Care/Services Rendered",
"code": "AB"
},
"AC": {
"description": "Inconvenient Office Location",
"code": "AC"
},
"AD": {
"description": "Dissatisfaction with Office Hours",
"code": "AD"
},
"AE": {
"description": "Unable to Schedule Appointments in a Timely Manner",
"code": "AE"
},
"AF": {
"description": "Dissatisfaction with Physician's Referral Policy",
"code": "AF"
},
"AG": {
"description": "Less Respect and Attention Time Given than to Other Patients",
"code": "AG"
},
"AH": {
"description": "Patient Moved to a New Location",
"code": "AH"
},
"AI": {
"description": "No Reason Given",
"code": "AI"
},
"AJ": {
"description": "Appointment Times not Met in a Timely Manner",
"code": "AJ"
}
},
"x12-usage-notes": "- If none of the specific Maintenance Reasons apply, send 'AI', No Reason Given."
}
},
"required": [
"action_code_01",
"entity_identifier_code_02",
"provider_effective_date_03",
"maintenance_reason_code_05"
],
"title": "Provider Change Reason",
"type": "object",
"x12-usage-notes": "- Required to report the reason and the effective date that a member changes providers as described by the NM1 segment in Loop 2310. If not required by this implementation guide, do not send."
}
},
"required": [
"provider_information_LX",
"provider_name_NM1"
],
"title": "Provider Information Loop",
"type": "object"
},
"maxItems": 30,
"minItems": 1,
"type": "array"
},
"coordination_of_benefits_COB_loop": {
"items": {
"additionalProperties": false,
"properties": {
"coordination_of_benefits_COB": {
"additionalProperties": false,
"description": "To supply information on coordination of benefits",
"properties": {
"payer_responsibility_sequence_number_code_01": {
"description": "Code identifying the insurance carrier's level of responsibility for a payment of a claim",
"enum": ["P", "S", "T", "U"],
"title": "Payer Responsibility Sequence Number Code",
"type": "string",
"x12-codes": {
"P": {
"description": "Primary",
"code": "P"
},
"S": {
"description": "Secondary",
"code": "S"
},
"T": {
"description": "Tertiary",
"code": "T"
},
"U": {
"description": "Unknown",
"code": "U"
}
}
},
"member_group_or_policy_number_02": {
"description": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier\n\n- COB02 is the policy number.",
"maxLength": 50,
"minLength": 1,
"title": "Member Group or Policy Number",
"type": "string"
},
"coordination_of_benefits_code_03": {
"description": "Code identifying whether there is a coordination of benefits",
"enum": ["1", "5", "6"],
"title": "Coordination of Benefits Code",
"type": "string",
"x12-codes": {
"1": {
"description": "Coordination of Benefits",
"code": "1"
},
"5": {
"description": "Unknown",
"code": "5"
},
"6": {
"description": "No Coordination of Benefits",
"code": "6",
"x12-usage-notes": "This code is sent when it has been determined that there is no COB."
}
}
},
"service_type_code_04": {
"items": {
"description": "Code identifying the classification of service",
"enum": [
"1",
"35",
"48",
"50",
"54",
"89",
"90",
"A4",
"AG",
"AL",
"BB"
],
"title": "Service Type Code",
"type": "string",
"x12-codes": {
"1": {
"description": "Medical Care",
"code": "1"
},
"35": {
"description": "Dental Care",
"code": "35"
},
"48": {
"description": "Hospital - Inpatient",
"code": "48"
},
"50": {
"description": "Hospital - Outpatient",
"code": "50"
},
"54": {
"description": "Long Term Care",
"code": "54"
},
"89": {
"description": "Free Standing Prescription Drug",
"code": "89"
},
"90": {
"description": "Mail Order Prescription Drug",
"code": "90"
},
"A4": {
"description": "Psychiatric",
"code": "A4"
},
"AG": {
"description": "Skilled Nursing Care",
"code": "AG"
},
"AL": {
"description": "Vision (Optometry)",
"code": "AL"
},
"BB": {
"description": "Partial Hospitalization (Psychiatric)",
"code": "BB"
}
}
},
"maxItems": 9,
"minItems": 1,
"type": "array"
}
},
"required": [
"payer_responsibility_sequence_number_code_01",
"coordination_of_benefits_code_03"
],
"title": "Coordination of Benefits",
"type": "object",
"x12-usage-notes": "- Required whenever an individual has another insurance plan with benefits similar to those covered by the insurance product specified in the HD segment for this occurrence of Loop ID-2300. If not required by this implementation guide, do not send."
},
"additional_coordination_of_benefits_identifiers_REF": {
"items": {
"additionalProperties": false,
"description": "To specify identifying information",
"properties": {
"reference_identification_qualifier_01": {
"description": "Code qualifying the Reference Identification",
"enum": ["6P", "60", "SY", "ZZ"],
"title": "Reference Identification Qualifier",
"type": "string",
"x12-codes": {
"60": {
"description": "Account Suffix Code",
"code": "60"
},
"6P": {
"description": "Group Number",
"code": "6P"
},
"SY": {
"description": "Social Security Number",
"code": "SY",
"x12-usage-notes": "The social security number may not be used for any Federally administered programs such as Medicare or CHAMPUS/TRICARE."
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ",
"x12-usage-notes": "Mutually Defined, will be used in this REF01 for National Individual Identifier until a standard code is defined."
}
}
},
"member_group_or_policy_number_02": {
"description": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier",
"maxLength": 50,
"minLength": 1,
"title": "Member Group or Policy Number",
"type": "string"
}
},
"required": [
"reference_identification_qualifier_01",
"member_group_or_policy_number_02"
],
"title": "Additional Coordination of Benefits Identifiers",
"type": "object",
"x12-usage-notes": "- Required if additional COB identifiers are supplied by the subscriber. If not required by this implementation guide, do not send.\n- Use the Social Security Number until the National ID Number for individuals is available."
},
"maxItems": 4,
"minItems": 1,
"type": "array"
},
"coordination_of_benefits_eligibility_dates_DTP": {
"items": {
"additionalProperties": false,
"description": "To specify any or all of a date, a time, or a time period",
"properties": {
"date_time_qualifier_01": {
"description": "Code specifying type of date or time, or both date and time",
"enum": ["344", "345"],
"title": "Date Time Qualifier",
"type": "string",
"x12-codes": {
"344": {
"description": "Coordination of Benefits Begin",
"code": "344"
},
"345": {
"description": "Coordination of Benefits End",
"code": "345"
}
}
},
"date_time_period_format_qualifier_02": {
"description": "Code indicating the date format, time format, or date and time format\n\n- DTP02 is the date or time or period format that will appear in DTP03.",
"enum": ["D8"],
"title": "Date Time Period Format Qualifier",
"type": "string",
"x12-codes": {
"D8": {
"description": "Date Expressed in Format CCYYMMDD",
"code": "D8"
}
}
},
"coordination_of_benefits_date_03": {
"description": "Expression of a date, a time, or range of dates, times or dates and times",
"maxLength": 35,
"minLength": 1,
"title": "Coordination of Benefits Date",
"type": "string"
}
},
"required": [
"date_time_qualifier_01",
"date_time_period_format_qualifier_02",
"coordination_of_benefits_date_03"
],
"title": "Coordination of Benefits Eligibility Dates",
"type": "object",
"x12-usage-notes": "- Required when the submitter needs to send effective dates for coordination of benefits. If not required by this implementation guide, do not send."
},
"maxItems": 2,
"minItems": 1,
"type": "array"
},
"coordination_of_benefits_related_entity_NM1_loop": {
"items": {
"additionalProperties": false,
"properties": {
"coordination_of_benefits_related_entity_NM1": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "P0809",
"type": "object",
"dependentRequired": {
"identification_code_qualifier_08": [
"coordination_of_benefits_insurer_identification_code_09"
],
"coordination_of_benefits_insurer_identification_code_09": [
"identification_code_qualifier_08"
]
}
}
],
"description": "To supply the full name of an individual or organizational entity",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["36", "GW", "IN"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"36": {
"description": "Employer",
"code": "36"
},
"GW": {
"description": "Group",
"code": "GW"
},
"IN": {
"description": "Insurer",
"code": "IN"
}
}
},
"entity_type_qualifier_02": {
"description": "Code qualifying the type of entity\n\n- NM102 qualifies NM103.",
"enum": ["2"],
"title": "Entity Type Qualifier",
"type": "string",
"x12-codes": {
"2": {
"description": "Non-Person Entity",
"code": "2"
}
}
},
"coordination_of_benefits_insurer_name_03": {
"description": "Individual last name or organizational name",
"maxLength": 60,
"minLength": 1,
"title": "Coordination of Benefits Insurer Name",
"type": "string"
},
"identification_code_qualifier_08": {
"description": "Code designating the system/method of code structure used for Identification Code (67)",
"enum": ["FI", "NI", "XV"],
"title": "Identification Code Qualifier",
"type": "string",
"x12-codes": {
"FI": {
"description": "Federal Taxpayer's Identification Number",
"code": "FI"
},
"NI": {
"description": "National Association of Insurance Commissioners (NAIC) Identification",
"code": "NI"
},
"XV": {
"description": "Centers for Medicare and Medicaid Services PlanID",
"code": "XV",
"x12-usage-notes": "Use when reporting Health Plan ID (HPID) or Other Entity Identifier (OEID)."
}
}
},
"coordination_of_benefits_insurer_identification_code_09": {
"description": "Code identifying a party or other code",
"maxLength": 80,
"minLength": 2,
"title": "Coordination of Benefits Insurer Identification Code",
"type": "string"
}
},
"required": [
"entity_identifier_code_01",
"entity_type_qualifier_02"
],
"title": "Coordination of Benefits Related Entity",
"type": "object",
"x12-usage-notes": "- Required to send the name of the insurance company when provided to the sponsor. If not required by this implementation guide, do not send."
},
"coordination_of_benefits_related_entity_address_N3": {
"additionalProperties": false,
"description": "To specify the location of the named party",
"properties": {
"address_information_01": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Address Information",
"type": "string"
},
"address_information_02": {
"description": "Address information",
"maxLength": 55,
"minLength": 1,
"title": "Address Information",
"type": "string"
}
},
"required": ["address_information_01"],
"title": "Coordination of Benefits Related Entity Address",
"type": "object",
"x12-usage-notes": "- Required when detailed COB coverage information is agreed to be exchanged. If not required by this implementation guide, do not send."
},
"coordination_of_benefits_other_insurance_company_city_state_zip_code_N4": {
"additionalProperties": false,
"allOf": [
{
"x12-condition": "E0207",
"oneOf": [
{
"oneOf": [
{
"required": [
"coordination_of_benefits_other_insurance_company_state_code_02"
],
"type": "object",
"properties": {
"coordination_of_benefits_other_insurance_company_state_code_02": true
}
},
{
"required": [
"country_subdivision_code_07"
],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
},
{
"not": {
"anyOf": [
{
"required": [
"coordination_of_benefits_other_insurance_company_state_code_02"
],
"type": "object",
"properties": {
"coordination_of_benefits_other_insurance_company_state_code_02": true
}
},
{
"required": [
"country_subdivision_code_07"
],
"type": "object",
"properties": {
"country_subdivision_code_07": true
}
}
]
}
}
]
},
{
"type": "object",
"x12-condition": "C0704",
"dependentRequired": {
"country_subdivision_code_07": [
"country_code_04"
]
}
}
],
"description": "To specify the geographic place of the named party",
"properties": {
"coordination_of_benefits_other_insurance_company_city_name_01": {
"description": "Free-form text for city name\n\n- A combination of either N401 through N404, or N405 and N406 may be adequate to specify a location.",
"maxLength": 30,
"minLength": 2,
"title": "Coordination of Benefits Other Insurance Company City Name",
"type": "string"
},
"coordination_of_benefits_other_insurance_company_state_code_02": {
"description": "Code (Standard State/Province) as defined by appropriate government agency\n\n- N402 is required only if city name (N401) is in the U.S. or Canada.",
"maxLength": 2,
"minLength": 2,
"title": "Coordination of Benefits Other Insurance Company State Code",
"type": "string"
},
"coordination_of_benefits_other_insurance_company_postal_zone_or_zip_code_03": {
"description": "Code defining international postal zone code excluding punctuation and blanks (zip code for United States)",
"maxLength": 15,
"minLength": 3,
"title": "Coordination of Benefits Other Insurance Company Postal Zone or ZIP Code",
"type": "string"
},
"country_code_04": {
"description": "Code identifying the country",
"maxLength": 3,
"minLength": 2,
"title": "Country Code",
"type": "string",
"x12-usage-notes": "- Use the alpha-2 country codes from Part 1 of ISO 3166."
},
"country_subdivision_code_07": {
"description": "Code identifying the country subdivision",
"maxLength": 3,
"minLength": 1,
"title": "Country Subdivision Code",
"type": "string",
"x12-usage-notes": "- Use the country subdivision codes from Part 2 of ISO 3166."
}
},
"required": [
"coordination_of_benefits_other_insurance_company_city_name_01"
],
"title": "Coordination of Benefits Other Insurance Company City, State, ZIP Code",
"type": "object",
"x12-usage-notes": "- Required when detailed COB coverage information is agreed to be exchanged. If not required by this implementation guide, do not send."
},
"administrative_communications_contact_PER": {
"additionalProperties": false,
"description": "To identify a person or office to whom administrative communications should be directed",
"properties": {
"contact_function_code_01": {
"description": "Code identifying the major duty or responsibility of the person or group named",
"enum": ["CN"],
"title": "Contact Function Code",
"type": "string",
"x12-codes": {
"CN": {
"description": "General Contact",
"code": "CN"
}
}
},
"communication_number_qualifier_03": {
"description": "Code identifying the type of communication number",
"enum": ["TE"],
"title": "Communication Number Qualifier",
"type": "string",
"x12-codes": {
"TE": {
"description": "Telephone",
"code": "TE"
}
}
},
"communication_number_04": {
"description": "Complete communications number including country or area code when applicable",
"maxLength": 256,
"minLength": 1,
"title": "Communication Number",
"type": "string"
}
},
"required": [
"contact_function_code_01",
"communication_number_qualifier_03",
"communication_number_04"
],
"title": "Administrative Communications Contact",
"type": "object",
"x12-usage-notes": "- Required when detailed COB coverage information is agreed to be exchanged. If not required by this implementation guide, do not send."
}
},
"required": [
"coordination_of_benefits_related_entity_NM1"
],
"title": "Coordination of Benefits Related Entity Loop",
"type": "object"
},
"maxItems": 3,
"minItems": 1,
"type": "array"
}
},
"required": ["coordination_of_benefits_COB"],
"title": "Coordination of Benefits Loop",
"type": "object"
},
"maxItems": 5,
"minItems": 1,
"type": "array"
}
},
"required": ["health_coverage_HD", "health_coverage_dates_DTP"],
"title": "Health Coverage Loop",
"type": "object"
},
"maxItems": 99,
"minItems": 1,
"type": "array"
},
"member_reporting_categories_LX_loop": {
"items": {
"additionalProperties": false,
"properties": {
"member_reporting_categories_LX": {
"additionalProperties": false,
"description": "To reference a line number in a transaction set",
"properties": {
"assigned_number_01": {
"description": "Number assigned for differentiation within a transaction set",
"title": "Assigned Number",
"type": "integer",
"x12-usage-notes": "- Use this sequential non-negative integer for LX loops for this member's additional reporting categories.",
"x12-max-length": 6,
"minimum": -999999,
"maximum": 999999
}
},
"required": ["assigned_number_01"],
"title": "Member Reporting Categories",
"type": "object",
"x12-usage-notes": "- Required when needed to provide additional reporting categories about the member. If not required by this implementation guide, do not send."
},
"reporting_category_N1_loop": {
"additionalProperties": false,
"properties": {
"reporting_category_N1": {
"additionalProperties": false,
"description": "To identify a party by type of organization, name, and code",
"properties": {
"entity_identifier_code_01": {
"description": "Code identifying an organizational entity, a physical location, property or an individual",
"enum": ["75"],
"title": "Entity Identifier Code",
"type": "string",
"x12-codes": {
"75": {
"description": "Participant",
"code": "75"
}
}
},
"member_reporting_category_name_02": {
"description": "Free-form name",
"maxLength": 60,
"minLength": 1,
"title": "Member Reporting Category Name",
"type": "string"
}
},
"required": [
"entity_identifier_code_01",
"member_reporting_category_name_02"
],
"title": "Reporting Category",
"type": "object",
"x12-usage-notes": "- Required to specify the name of the reporting category of the member's participating entity."
},
"reporting_category_reference_REF": {
"additionalProperties": false,
"description": "To specify identifying information",
"properties": {
"reference_identification_qualifier_01": {
"description": "Code qualifying the Reference Identification",
"enum": [
"00",
"3L",
"6M",
"9V",
"9X",
"17",
"18",
"19",
"26",
"GE",
"LU",
"PID",
"XX1",
"XX2",
"YY",
"ZZ"
],
"title": "Reference Identification Qualifier",
"type": "string",
"x12-codes": {
"17": {
"description": "Client Reporting Category",
"code": "17"
},
"18": {
"description": "Plan Number",
"code": "18"
},
"19": {
"description": "Division Identifier",
"code": "19"
},
"26": {
"description": "Union Number",
"code": "26"
},
"00": {
"description": "Contracting District Number",
"code": "00"
},
"3L": {
"description": "Branch Identifier",
"code": "3L"
},
"6M": {
"description": "Application Number",
"code": "6M"
},
"9V": {
"description": "Payment Category",
"code": "9V"
},
"9X": {
"description": "Account Category",
"code": "9X"
},
"GE": {
"description": "Geographic Number",
"code": "GE"
},
"LU": {
"description": "Location Number",
"code": "LU"
},
"PID": {
"description": "Program Identification Number",
"code": "PID"
},
"XX1": {
"description": "Special Program Code",
"code": "XX1"
},
"XX2": {
"description": "Service Area Code",
"code": "XX2"
},
"YY": {
"description": "Geographic Key",
"code": "YY"
},
"ZZ": {
"description": "Mutually Defined",
"code": "ZZ"
}
}
},
"member_reporting_category_reference_id_02": {
"description": "Reference information as defined for a particular Transaction Set or as specified by the Reference Identification Qualifier",
"maxLength": 50,
"minLength": 1,
"title": "Member Reporting Category Reference ID",
"type": "string"
}
},
"required": [
"reference_identification_qualifier_01",
"member_reporting_category_reference_id_02"
],
"title": "Reporting Category Reference",
"type": "object",
"x12-usage-notes": "- Required to specify the reference identifier associated with the reporting category of the member's participating entity."
},
"reporting_category_date_DTP": {
"additionalProperties": false,
"description": "To specify any or all of a date, a time, or a time period",
"properties": {
"date_time_qualifier_01": {
"description": "Code specifying type of date or time, or both date and time",
"enum": ["007"],
"title": "Date Time Qualifier",
"type": "string",
"x12-codes": {
"007": {
"description": "Effective",
"code": "007"
}
}
},
"date_time_period_format_qualifier_02": {
"description": "Code indicating the date format, time format, or date and time format\n\n- DTP02 is the date or time or period format that will appear in DTP03.",
"enum": ["D8", "RD8"],
"title": "Date Time Period Format Qualifier",
"type": "string",
"x12-codes": {
"D8": {
"description": "Date Expressed in Format CCYYMMDD",
"code": "D8"
},
"RD8": {
"description": "Range of Dates Expressed in Format CCYYMMDD-CCYYMMDD",
"code": "RD8",
"x12-usage-notes": "A range of dates expressed in the format CCYYMMDD-CCYYMMDD where CCYY is the numerical expression of the century CC and year YY. MM is the numerical expression of the month within the year, and DD is the numerical expression of the day within the year; the first occurrence of CCYYMMDD is the beginning date and the second occurrence is the ending date."
}
}
},
"member_reporting_category_effective_dates_03": {
"description": "Expression of a date, a time, or range of dates, times or dates and times",
"maxLength": 35,
"minLength": 1,
"title": "Member Reporting Category Effective Date(s)",
"type": "string"
}
},
"required": [
"date_time_qualifier_01",
"date_time_period_format_qualifier_02",
"member_reporting_category_effective_dates_03"
],
"title": "Reporting Category Date",
"type": "object",
"x12-usage-notes": "- Required when called for in the insurance contract between the sponsor and payer. If not required by this implementation guide, do not send.\n- Use this segment to associate a date or date range with a reporting category."
}
},
"required": ["reporting_category_N1"],
"title": "Reporting Category Loop",
"type": "object"
}
},
"required": ["member_reporting_categories_LX"],
"title": "Member Reporting Categories Loop",
"type": "object"
},
"minItems": 1,
"type": "array"
}
},
"required": [
"member_level_detail_INS",
"subscriber_identifier_REF",
"member_name_NM1_loop"
],
"title": "Member Level Detail Loop",
"type": "object"
},
"minItems": 1,
"type": "array"
}
},
"required": ["member_level_detail_INS_loop"],
"type": "object"
}
```
## Find the mapping ID and schema
If you plan to use a mapping to transform fragments into Stedi’s Guide JSON format, you must send fragments to Stedi's API in the mapping's source JSON schema.
To find the mapping ID and schema:
1. Go to the [Mappings page](https://portal.stedi.com/app/mappings) and copy the **ID** field for the mapping you want to use.
2. Click the mapping's name to view its details.
3. Click **Test mapping**. The test input JSON shape is the shape you must use when sending fragment data to the Stage Fragment API.
## Stage fragments
Call the [Stage Fragments API](/api-reference/edi-platform/core/post-fragments) to store a fragment on Stedi until you are ready to generate an outbound EDI file.
Stedi stores fragments in groups, specified by the `fragmentGroupID` included in the path. You can call the API with the same `fragmentGroupID` as many times as needed until you have staged all of the fragments required for the transaction.
### Data format
For each staging call, you can optionally specify a mapping that Stedi will use to transform the fragment from your system's JSON format into Stedi’s Guide JSON format.
* If you don’t use a mapping, the fragment must match the Guide JSON format for the specified guide.
* If you use a mapping, the fragment must match the mapping's source JSON schema.
### Sample request and response
The following example shows a cURL request and response for staging a fragment without a mapping. The fragment contains iterations of `Loop 2000` (Member Level Detail) in an 834 Healthcare Benefit Enrollment.
```shell
curl --request POST \
--url https://core.us.stedi.com/2023-08-01/fragments/{fragmentGroupId} \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"guideId": "01HQ1XPE9C3SCEB2ND7VC53A8M",
"fragment": {
"member_level_detail_INS_loop": [ ... ]
}
}'
```
```shell
curl --request POST \
--url https://core.us.stedi.com/2023-08-01/fragments/{fragmentGroupId} \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"guideId": "01HQ1XPE9C3SCEB2ND7VC53A8M",
"fragment": {
"member_level_detail_INS_loop": [
{
"member_level_detail_INS": {
"member_indicator_01": "Y",
"individual_relationship_code_02": "18",
"maintenance_type_code_03": "001",
"maintenance_reason_code_04": "22",
"benefit_status_code_05": "A",
"employment_status_code_08": "FT"
},
"member_policy_number_REF": {
"reference_identification_qualifier_01": "1L",
"member_group_or_policy_number_02": "123456001"
},
"subscriber_identifier_REF": {
"reference_identification_qualifier_01": "0F",
"subscriber_identifier_02": "202443307"
},
"member_name_NM1_loop": {
"member_name_NM1": {
"entity_identifier_code_01": "IL",
"entity_type_qualifier_02": "1",
"member_last_name_03": "SMITH",
"member_first_name_04": "WILLIAM",
"identification_code_qualifier_08": "ZZ",
"member_identifier_09": "2024433307"
}
},
"health_coverage_HD_loop": [
{
"health_coverage_HD": {
"maintenance_type_code_01": "021",
"insurance_line_code_03": "DEN"
},
"health_coverage_dates_DTP": [
{
"date_time_qualifier_01": "348",
"date_time_period_format_qualifier_02": "D8",
"coverage_period_03": "20020701"
}
]
}
]
}
]
}
}'
```
```json
{
"fragmentGroupId": "some-transaction-id",
"createdAt": "2024-02-21T00:00:00Z",
"fragmentId": "d3b3e3e3-3e3e-3e3e-3e3e-3e3e3e3e3e3e"
}
```
## Create outbound transaction
Call the [Create Outbound Transaction API](/api-reference/edi-platform/post-transactions) and Stedi combines all of the fragments matching the `fragmentGroupId` into a single, compliant EDI file and delivers it to your trading partner.
Once you call the Transaction API with a `fragmentGroupId`, that ID is locked, meaning that you cannot add new fragments to the group and you cannot call the API again with that ID. This feature prevents you from accidentally sending duplicate data to partners.
### Data format
When calling the API with fragments, you provide a *fragment wrapper* for the transaction. The wrapper contains all of the transaction data except for the contents of the repeated loop segment where Stedi should insert the fragments. Instead, you leave an empty array in place of the loop contents - for example, `member_level_detail_INS_loop: []`.
```json
"transaction": {
"heading": {
"transaction_set_header_ST": {
"transaction_set_identifier_code_01": "834",
"transaction_set_control_number_02": 12345,
"implementation_convention_reference_03": "005010X220A1"
},
"beginning_segment_BGN": {
"transaction_set_purpose_code_01": "00",
"transaction_set_reference_number_02": "12456",
"transaction_set_creation_date_03": "1998-05-20",
"transaction_set_creation_time_04": "12:00",
"action_code_08": "2"
},
"payer_N1_loop": {
"payer_N1": {
"entity_identifier_code_01": "IN",
"identification_code_qualifier_03": "FI",
"insurer_identification_code_04": "654456654"
}
},
"sponsor_name_N1_loop": {
"sponsor_name_N1": {
"entity_identifier_code_01": "P5",
"identification_code_qualifier_03": "FI",
"sponsor_identifier_04": "999888777"
}
}
},
"detail": {
"member_level_detail_INS_loop": []
}
}
```
You can optionally provide a mapping ID to transform the fragment wrapper from your system's JSON format into Stedi’s Guide JSON format. If you don't use a mapping, the fragment wrapper must match the Guide JSON format for the specified guide.
### Sample request and response
The following example shows a cURL request and response to generate an [834 Benefit Enrollment and Maintenance](https://portal.stedi.com/app/guides/view/hipaa/benefit-enrollment-and-maintenance-x220a1/01GRYB6D6RAWSG8ATBD6GXM13C). Notice that the `member_level_detail_INS_loop` is an empty array - this is where Stedi will insert the fragments from the specified fragment group.
```shell
curl --location 'https://core.us.stedi.com/2023-08-01/partnerships//transactions/' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Key ' \
--data '
{
"fragmentGroupId": "plan_file_2023-12-12",
"transaction": {
"heading": {},
"detail": {}
}
}'
```
```shell
curl --location 'https://core.us.stedi.com/2023-08-01/partnerships//transactions/' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Key ' \
--data '
{
"fragmentGroupId": "plan_file_2023-12-12",
"transaction": {
"heading": {
"transaction_set_header_ST": {
"transaction_set_identifier_code_01": "834",
"transaction_set_control_number_02": 12345,
"implementation_convention_reference_03": "005010X220A1"
},
"beginning_segment_BGN": {
"transaction_set_purpose_code_01": "00",
"transaction_set_reference_number_02": "12456",
"transaction_set_creation_date_03": "1998-05-20",
"transaction_set_creation_time_04": "12:00",
"action_code_08": "2"
},
"payer_N1_loop": {
"payer_N1": {
"entity_identifier_code_01": "IN",
"identification_code_qualifier_03": "FI",
"insurer_identification_code_04": "654456654"
}
},
"sponsor_name_N1_loop": {
"sponsor_name_N1": {
"entity_identifier_code_01": "P5",
"identification_code_qualifier_03": "FI",
"sponsor_identifier_04": "999888777"
}
}
},
"detail": {
"member_level_detail_INS_loop": []
}
}
}'
```
```json
{
"fileExecutionId": "d3b3e3e3-3e3e-3e3e-3e3e-3e3e3e3e3e3e"
}
```
## Retrieve an outbound transaction with fragments
Call the [Get Transaction](/api-reference/edi-platform/core/get-transactions) endpoint to retrieve the full transaction, including the fragment data. Note that the full transaction, including fragments, can be very large.
# Integration steps
Source: https://www.stedi.com/docs/edi-platform/getting-started/first-integration
***
title: Integration steps
sidebarTitle: "Integration steps"
icon: ""
description: ""
---------------
Complete the following steps to configure and test your first EDI integration on Stedi.
## Configure your first trading partner
Time: About 15 minutes
To set up a new trading partner, you'll need to configure the following settings:
* [Partnership](/edi-platform/configure/trading-partners/profiles-and-partnerships): Partnerships describe all aspects of the EDI relationship between you and your trading partner, including which transaction sets you plan to exchange and other important information for processing.
* [Connections](/edi-platform/configure/trading-partners/connections): Within the partnership, define SFTP/FTP/FTPS and AS2 connections to exchange data with partners.
* [Transaction settings](/edi-platform/configure/trading-partners/transaction-settings): Within the partnership, define the inbound and outbound transaction sets you plan to exchange with your trading partner. As part of this process, you'll choose which EDI specifications to use to validate the data.
## Send webhooks to your system
Time: About 5 minutes
Each time Stedi processes an EDI file from a trading partner, you will want to ingest the transactions into your downstream system. You can do this by configuring a [webhook](/edi-platform/configure/webhooks) to send [transaction.processed.v2\` events](/edi-platform/operate/event-types#transaction-processed) to your API, Cloud functions, IPaaS platforms, or ERP systems. Then, you can programmatically retrieve the processed transaction data from Stedi.
You can also configure webhooks for other events, like when a processing error occurs. You can use this approach to trigger alerts in systems like Slack, PagerDuty, or Zendesk for further review.
## Process an inbound test file
Time: About 2 minutes
Once you have configured your first trading partner and a webhook, you can process a test file to make sure your partner configuration is working correctly. If you don't want to wait for a test file from your partner, you can also [generate a test file](/edi-platform/operate/generate-test-files).
When the test file is successfully processed, you will receive a webhook for each included transaction.
## Send an outbound test file
Time: About 2 minutes
You can [send a test file](/edi-platform/operate/generate-test-files) to your partner from within the browser.
This is also useful for understanding what data is required to call the [Generate API](/edi-platform/operate/generate-edi) programmatically from your system. You can export cURL commands to use as a starting point for your live integration.
## Configure data transformations
Time: A few hours
To complete your integration, [choose an approach](/edi-platform/operate/transform-json/transformation-approaches) to transform [Stedi Guide JSON format](/edi-platform/operate/transform-json/guide-json) into and out of the format your internal systems can understand.
# Gather requirements
Source: https://www.stedi.com/docs/edi-platform/getting-started/gather-requirements
***
title: Gather requirements
sidebarTitle: 'Gather requirements'
icon: ''
description: ''
---------------
Complete the following steps in preparation for onboarding your first trading partner. Please [contact us](https://www.stedi.com/contact) with any questions.
## Project planning
Work with your team to determine the following details:
* **Trading partner:** Select a trading partner to integrate with. If you have multiple trading partners, we recommend starting with the partner that is either easiest to work with or that has the earliest implementation deadline.
* **Timeline:** Determine your ideal implemention timeline and any hard deadlines for when the integration must be production-ready. Communicate these to your customer success engineer as soon as possible.
* **Team members:** Identify the team members who will be involved in the integration. We recommend at least one project or program manager to communicate with trading partners and keep the integration on track and one engineer or technical team member.
* [EDI IDs](#edi-ids): You need IDs for both your business and your trading partner before you can configure your Stedi account.
## Contact your trading partner
Ask your trading partner for the following information. You and your customer success engineer will use it to configure your account.
### EDI requirements
Create a list of all the EDI transaction types you plan to send or receive.
* **Guides:** Ask your partner for the most up-to-date EDI requirements for each transaction type. Your partner may provide these as PDF, Excel, or Word documents.
These requirements may already be available in the [Stedi
Network](https://www.stedi.com/edi/network). If so, we'll use the documents
you provide to ensure the Network guides are up-to-date. If not, we'll add
the guides you need to the Network in 1-2 business days.
### EDI IDs
Determine the following IDs for both you and your trading partner. You can use the IDs in existing production EDI files or ask your trading partner to provide them.
* [`ISA` ID](https://www.stedi.com/edi/x12/segment/ISA#ISA-06): Codes included in each EDI file's ISA header (`ISA06` or `ISA08`) to identify your and your partner's organization. In logistics and retail, this is often a derivative of the company name. For example, `AMAZONDS` for Amazon Dropshipping. In healthcare, this may be the Payer ID, such as `87726` for UnitedHealthcare or another value.
* [`ISA` Qualifier](https://www.stedi.com/edi/x12/segment/ISA#ISA-05): The type of ISA ID. If you're not sure what to choose for your business, we recommend `ZZ (Mutually Defined)`.
* [Application Code](https://www.stedi.com/edi/x12-008010/segment/GS#GS-02): Codes included in each EDI file's GS header (`GS02` or `GS03`) to identify your and your partner's organization. The Application Code for a business is typically the same as its `ISA` ID, but not always.
If you're new to EDI, we can help you choose values for your business.
### Connection protocol
Determine how you will exchange EDI files with your partner and gather configuration details.
* **Stedi-hosted SFTP/FTPS (recommended):** No additional information is required for configuration. We'll provide credentials your partner can use to connect to the server.
* **Remote SFTP/FTPS:** If your partner is hosting the remote server, ask them to provide the following information:
* Protocol - FTP, FTPS, SFTP
* Host - server URL/address
* Port number
* Password or key passphrase
* Root directory
* Directories to retrieve files from your trading partner (inbound) and to deliver files to your trading partner (outbound)
* **AS2:** This connection type is complex. If your partner requires AS2, we will discuss the requirements during your onboarding call. You can also check out our [AS2 documentation](/edi-platform/configure/trading-partners/connections/as2/as2-overview) for more information.
### Sample EDI files
Gather production EDI files or ask your partner for sample files that you can use to test the integration.
Trading partners often send files that do not fully conform to their official EDI requirements, so it's critical to test your pipeline with real-world data before your go-live date.
# EDI platform overview
Source: https://www.stedi.com/docs/edi-platform/getting-started
***
title: EDI platform overview
sidebarTitle: "Platform overview"
icon: ""
--------
In addition to our [Healthcare APIs](/healthcare), Stedi offers a platform for building and managing end-to-end EDI systems in any industry. The platform encapsulates the complexity of EDI and helps you integrate with external systems, such as Electronic Medical Record (EMR) platforms, Revenue Cycle Management (RCM) platforms, and other custom applications.
You may want to use Stedi's EDI platform if you are:
* A payer or third-party organization that needs to ingest claims as well as generate Electronic Remittance Advice (ERAs) and claim status transactions.
* A business that needs to exchange 834 Benefit Enrollments and related information between employers, insurance carriers, and benefit administrators.
* A software vendor that needs to ingest X12 EDI transactions (such as claims or ERAs) for downstream analysis or processing for your customers.
## Build an EDI system on Stedi
Stedi acts as an EDI translation layer.
You send JSON to Stedi, and Stedi generates EDI files and delivers them to your trading partners. Your trading partners send EDI to Stedi, and Stedi automatically translates those files into JSON and sends them to your business systems.

There are two main aspects to building an EDI system on Stedi.
### Onboard trading partners
A trading partner is an entity with whom you want to exchange transactions. For example, as a payer sending Electronic Remittance Advice (ERA) transactions through Stedi, your trading partners would be providers.
Anyone, regardless of their technical background or EDI experience, can add a trading partner configuration to Stedi in about 15 minutes. This involves defining the transaction sets you plan to exchange with that partner and the communication methods you plan to use (e.g. SFTP/FTPS or AS2).
We can help you during a free onboarding call, or you can follow our [step-by-step instructions](/edi-platform/configure/trading-partners/profiles-and-partnerships).
### Integrate Stedi with internal systems
After you configure your trading partner, you will set up pipelines to get transaction data into and out of Stedi. A developer can do this, or our [onboarding team](https://www.stedi.com/contact) can do it for you for free.
* For each inbound transaction you receive from your trading partner, you can set up webhooks that forward processed data and events from Stedi to your systems.
* For each outbound transaction you want to send to your trading partner, you can make a Stedi API call to generate and deliver fully-formed EDI files.
As part of this process, you will [transform transaction data](/edi-platform/operate/transform-json/transforming-data) to and from a format that your internal systems can understand.
# Advanced: Build Stedi guides
Source: https://www.stedi.com/docs/edi-platform/guides/customize-guides
***
title: 'Advanced: Build Stedi guides'
sidebarTitle: 'Advanced: Build guides'
--------------------------------------
You can create, import, and customize guides for any of the 300+ X12 transaction sets.
Most users don't need to build custom guides - we strongly recommend importing your trading partner's guides from the [Stedi Network](https://www.stedi.com/edi/network) into your account for free. If you're sending or receiving X12 HIPAA transactions, you definitely don't need to build custom guides - you should use the pre-built [X12 HIPAA guides](https://www.stedi.com/edi/network/hipaa) in the network as is.
However, many logistics and retail trading partners send EDI files that are not 100% compliant with their official guide for a transaction set. For example, they may use different codes for an element. In these cases, you can edit existing guides so that they accurately represent the EDI files you receive.
**Not sure what to fix?** If you received a guide-related file execution
error, [contact us](https://www.stedi.com/contact) for help updating your
guide to fix the issue.
## Edit existing guides
Go to your [Stedi account](https://portal.stedi.com/app/guides) and find the guide you want to edit.
To edit, click the **ellipses (…)** next to the guide and select **Edit**. The guide opens in the guide builder.
## Create guides
You can create a custom guide from the base specification for a transaction set from any X12 release. To create a guide:
1. Go to your [Stedi account](https://portal.stedi.com/app) and click **Create guide**.
2. Select an **X12 Release** and the **Transaction Set** base specfication you want to customize.
3. Enter a unique **Name** for your guide and click **Create**. The new guide opens in the guide builder.
## Lock guides
When you're finished editing, you can lock a guide to prevent further updates. Locking helps prevent accidental changes or deletions to guides in production.
Any user in your Stedi account can lock guides, but only an account admin can unlock guides.
To lock a guide, go to the **Actions** menu and select **Lock**. No one can update, delete, or publish a locked guide. However, you can duplicate locked guides, if needed.
To unlock the guide, an admin can go to the **Actions** menu and select **Unlock**.
## Segments and Loops
By default, the guide builder only lists the [segments](https://www.stedi.com/edi/essentials/x12/segments) required in the base transaction set. You can add additional segments to your custom guide.
To add additional segments:
1. Click either **Heading**, **Detail**, or **Summary** in the left sidebar to view a list of the possible segments for that section.
2. Click the box next to each segment to change whether it is included in the transaction set.
* `R`: Required. Note: Some PDF implementation guides use a designation of `M` (for Mandatory) instead. In these cases, `R` is still the appropriate choice.
* `O`: Optional.
* `N`: Not used by this implementation guide.
### Hierarchical Levels
An `HL` segment identifies dependencies between hierarchically related data segments. For example, there may be hierarchical relationships between components of packing information in an [856 Ship Notice](https://www.stedi.com/edi/x12/transaction-set/856).
#### Example use case
Consider the following hierarchical information about customer grocery orders.
```
ORD02208
├── Package
├── Milk
```
The following EDI example shows the HL loops that define this information.
```
HL*1**O*1~
PRF*ORD02208***20220815~
HL*2*1*P*1~
TD1*CTN*1~
REF*CN*1B487311569~
HL*3*2*I*0~
LIN*D002*BN*75206331361~
SN1**1*EA~
PID*F*TRN***MILK~
```
The first `HL` segment defines the order at the highest level of the hierarchy. It has four elements.
| Element | Name | Description |
| ------- | ---------------- | --------------------------------------------------------- |
| `HL-01` | ID Number | Identifies this entry of the HL loop. |
| `HL-02` | Parent ID Number | The ID Number of the order that this package relates to. |
| `HL-03` | Level Code | Specifies the type of the entry. In this case, a package. |
| `HL-04` | Child Code | Specifies whether this entry has children. `1` means yes. |
Then, the document continues:
* The `PRF` segment contains information about the order itself, including the order number `ORD02208`.
* The `HL` segment repeats when the order becomes a package, and the package itself is described by the segments `TD1` and `REF`.
* the `HL` segment repeats once more when the order contains an item, and the item itself is described by the segments `LIN`, `SN1`, and `PID`.
#### Add an HL loop to your guide
X12 does not enforce a specific hierarchy in your transaction set. You can add `HL` loops to your Stedi guide to define the hierarchical relationships you need for your use case.
You must add `HL` loops to your guides one level at a time. For example, you would create three nested `HL` segments to capture the following hierarchy.
```
Order
├── Package
├── Item
```
To add an `HL` loop for this scenario:
1. Click the **DETAIL** heading in the left sidebar.
2. Click the box next to the HL Loop to change its status from **Not Used**.
3. Choose a code to describe the type of entry for this level of the hierarchy. In this example, you would choose `O` for order.
4. Click **Save** to add the HL segment under **DETAIL**.
5. Click the HL Loop, scroll to the list of HL segments.
6. Click the box next to **HL Loop** to add it and select a code. In this example, you'd select `P` for package.
7. Repeat this process for the final hierarchy level describing the item.
#### HL Loop Variations
Sometimes, an implementation guide allows for variations of a hierarchy. For example, if a ship notice only has one package, you can leave out the package information.
You can convey this information to your trading partners by creating [variants](#variants) within a single Stedi guide or by creating a separate Stedi guide for each variant.
### Variants
Loops and segments allow you to create variants. A variant is a specific version of a loop or a segment that is used in a particular context.
To create a variant, go to the segment and click **+ Create variant** under the **Variant group** section.
#### Variant sequence
Some trading partners require that you send certain iterations of loops or segments before others. To address these requirements, specify the **Variant sequence**, or position number, for each variant. This approach ensures that the variants appear in a specific order when you use this guide to write EDI.
Variants with lower numbers are written before higher numbers, and variants without a defined sequence are written last.
You can only set the variant sequence for loops or segments with a variant defined. To set the variant sequence, click the loop or segment you want to edit and open the **Advanced** menu.
#### Discriminants
Variants must be uniquely identifiable from each other. To do this, you must add a discriminant that differentiates each variant. The discriminant tells Stedi when one variant should be used over the other for validating, generating, or parsing EDI documents.
For example, you could specify that partners include two `N1 Name` loops in each `850` Purchase Order: one for the ship to contact and another for the bill to party. In this case you'd add the Entity Identifier Code as the discriminant for `N1 Name` loops. For the `bill to` variant, you'd use the `BT` qualifier, and for the ship to variant, you'd use the `ST` qualifier.
The type of discriminant depends on whether the loop is hierarchical:
* For hierarchical loops (HL loops), set a unique HL Level Code (`HL-03`) on each variant.
* For non-hierarchical loops and segments, set a unique allowed value on each variant.
You do not need to place the discriminant on the first element of the first segment. You can place it in any required element of the first segment. The only requirement is that the discriminant must be unique amongst all variants.
## Elements
By default, the guide builder only includes the [elements](https://www.stedi.com/edi/essentials/x12/elements) for each segment that are required in the base transaction set. You can add additional elements to your custom guide.
To add or remove elements from a segment:
1. Click the segment's name and scroll to find the list of possible elements.
2. Click the box next to each element to change whether it is included in the segment.
Some PDF guides have elements marked as conditional (`X`). These have special
rules associated with them. At this step, you should mark them as optional.
### Conditional elements
Some elements come with conditions that tell you when they should be included. For example, if you specify a date in the [date/time-segment](https://www.stedi.com/edi/x12/segment/G62), you must also specify a date qualifier. Similarly, if you specify a time, you must also specify a time qualifier. You can specify either a date or a time, but you must include at least one.
Every condition begins with a letter that specifies the type of condition, followed by one or more element numbers to which the condition applies. For example, `R0103` means that you must specify at least one of the elements `01` or `03`.
It’s possible to specify more than two elements, so `R010304` would mean that you must specify at least one of the elements `01`, `03`, or `04`.
| **Letter** | **Name** | **Condition** |
| ---------- | ---------------- | ----------------------------------------------------------------------------------------- |
| `C` | Condition | If the first element is present, then all the other elements must be present. |
| `E` | Exclusive | Only one of the elements may be present. |
| `L` | List conditional | If the first element is present, then at least one of the other elements must be present. |
| `P` | Paired | If one of the elements is present, then all elements must be present. |
| `R` | Required | At least one of the elements must be present. |
#### Add Conditions
You must specify conditions for elements on the segment level. To add conditions:
1. Click the segment name in the left sidebar.
2. Scroll to the **Conditions** section in the center column and click **+ Add condition**.
Learn more about [X12 EDI relational
conditions](/edi-platform/edi-essentials/x12/elements/relational-conditions-in-x12-edi)
in our EDI Reference documentation.
### Data type and length
Every element has a specific data type and length. Your guide automatically copies the data type and length settings from the base specification for the transaction set. Implementation guides typically use the same data type and length as the base specification, so we recommend leaving the default settings as is, unless you have a specific reason for updating them.
To edit the element's data type, click the element name in the sidebar and open the **Advanced** menu in the center column.
#### Maximum length of numeric elements
Numeric elements in Stedi Guides have a maximum length of 15. This differs from the X12 specification, which does not enforce a maximum length for numeric data element types. The reason for this discrepancy is that most common programming languages and libraries deserialize JSON numbers to double precision floating point numbers, which have a maximum of 15 digits of precision. This maximum length ensures that numbers do not have their value changed in the process.
By default, Guides has reduced the length of certain X12 data elements to improve usability. For example, X12 element `[212 Unit Price](https://www.stedi.com/edi/x12/element/212)` has a maximum length of 17. In Guides, this is reduced to 15 by default, since very few use cases legitimately require 17 digits of pricing precision.
If you need additional digits of precision, you can always change a numeric field to a string, which allows you to choose an arbitrary length.
When working with numbers where precision is important, we recommend deserializing to decimal types with the appropriate precision for your business case.
### Allowed values
Many elements have a value based on a standardized list of codes. For example, the date/time segment has the date qualifier segment, which indicates the type of date to include. The base specifiation lists well over a hundred possible codes. The implementation guide should list which ones are valid for you.
To update the list of accepted codes for an element:
1. Click the element's name in the left sidebar.
2. Scroll to the **Allowed values** section in the center column and click **+ Add code value**.
3. Add one or more codes that are appropriate for your use cases.
## Delimiters
Delimiters separate the segments and elements in an EDI file.
When you create a guide, you can set delimiters in the *Overview* pane in the top left. Stedi uses the guide's delimiters when [writing EDI](/edi-platform/operate/generate-edi).
As a default, Stedi recommends the following choices:
* Element: `*`
* Segment: `~`
* Repetition: `^`
* Component Element: `>`
Other common choices for the component element include `:`, `<`, and `\`.
Choosing delimiters for reading and writing EDI depends on your and your trading partner's data requirements. Clearly communicate the character restrictions with the business groups that are sending the data. You should also agree on substitution characters when a delimiter appears in the data. For example, if your delimiter is `*` and you know incoming data contains mathematical expressions, you could agree to use `x` instead of `*` for relevant expressions (`4x2` instead of `4*2`).
### Writing EDI
Stedi will parse your data incorrectly if the delimiter you choose appears elsewhere in your data. For example, if your input uses mathematical symbols, then we recommend choosing `:` or `\` instead of `>` and `<` as delimiters. Likewise, you may want to avoid `:` if your text data includes time values in `HH:MM:SS` format. We recommend considering the following guidance from the X12 documentation.
The following characters usually occur in data. They should not be used as delimiters:
* Upper (`A-Z`) and lowercase (`a-z`) letters
* Digits (`0-9`)
* Blank space (` `)
* Minus sign (`-`)
The following characters often appear in data. Use as delimiter characters with caution.
```
" ! & ' ( ) * + , - . / : ; ? =
```
The following characters sometimes appear in data. Use as delimiter characters with caution.
```
% @ [ ] \_ { } \ | < > ~ ^ `
```
### Reading EDI
#### Delimiters
We recommend allowing your trading partners to use any type of delimiter when sending data. They may have different data requirements and have likely already worked to ensure there are no conflicts with EDI delimiters.
Stedi automatically infers the delimiters from incoming EDI files.
#### X12 guidance for delimiters
X12 provides the following guidance about delimiters.
The following characters usually occur in data. They should not be used as delimiters:
* Upper (`A-Z`) and lowercase (`a-z`) letters
* Digits (`0-9`)
* Blank space (` `)
* Minus sign (`-`)
The following characters often appear in data. Use as delimiter characters with caution.
```
" ! & ' ( ) \* + , - . / : ; ? =
```
The following characters sometimes appear in data. Use as delimiter characters with caution.
```
% @ [ ] \_ { } \ | < > ~ ^ `
```
## Attachments
You can attach files to any Stedi guide and choose whether the attachments are public or private (only available to members of your Stedi account).
For example, you may want to add private attachments that help your team debug issues in your EDI pipeline, such as the original PDF specifications or a changelog. For a public guide, you may want to attach an appendix with a supplementary code list or a diagram that helps your partners understand the messaging flow.
To add attachments to a guide in your account, navigate to its **Overview** page, scroll to the **Attachments** section, and click **Attach file**.
## Sample EDI files for public guides
You can include multiple EDI sample files in Stedi guides to help new trading partners understand valid usage patterns faster and reduce onboarding time. The guide builder automatically validates each sample against the guide's specifications, so you can fix any errors before you provide them to trading partners.
You can also add a description to each sample that gives trading partners even more context about the intended use cases. The description appears at the top of the guide's EDI Inspector.
To add samples:
1. Click **Overview** in the left sidebar and scroll to the **EDI Samples** section in the center column. Click on **+ Add Sample**.
2. In the **EDI Sample** tab, add a **Name** and paste a sample file or customize an autogenerated sample based on the guide's specifications.
3. You may add an an optional **Description** in the **Description** tab.
4. Click **Create sample**.
EDI samples attached to the guide are used:
1. In the [Generate EDI test file](/edi-platform/operate/generate-test-files) flow.
2. On your [public guide's](/edi-platform/guides/public-guides) interactive web page and are included when partners download the guide as a PDF.
# Import Stedi Guides
Source: https://www.stedi.com/docs/edi-platform/guides/import-guides
***
title: Import Stedi Guides
sidebarTitle: 'Import guides'
-----------------------------
Most users don't need to create custom guides from scratch. Instead, we recommend importing guides from the [Stedi Network](https://www.stedi.com/edi/network) into your Stedi account.
### Import from our Network (Recommended)
To import your partner’s EDI guides:
1. Open the [Stedi Network](https://www.stedi.com/edi/network) in a new tab.
2. Locate the trading partner and guide you want to import. For healthcare transactions, search for `HIPAA` to find all available [X12 HIPAA guides](https://www.stedi.com/edi/network/hipaa).
3. Click the guide to go to its details page.
4. Click **Import guide into your account**.
5. (Optional) Update the guide name. For example, you may want to add the trading partner’s name, such as **Amazon - Purchase Order**. This is helpful when you have multiple trading partners with guides for the same transaction set.
6. Click **Import**.
The guide is available in your Stedi account, and you can attach it to one or more transaction settings.
### Import from another Stedi account
Your trading partners and collaborators can [enable import links](#enable-importing) for private guides that let you quickly add copies of those guides to your account.
**Public Guide import links:** All [Public
Guides](/edi-platform/guides/public-guides) have import links enabled by
default, regardless of these settings.
To import a guide from another Stedi account:
* Enter the guide's import link into your web browser. The Import page appears.
* Choose a **Name** for the guide and then click **Import**. A private copy of the guide appears in your Stedi account.
## Enable importing
You can enable an import link that allows other users to add a copy of a private guide into their Stedi account. When enabled, anyone with the import link can access your account name, guide name, and guide definition. You can disable import links at any time.
To enable an import link, click the **ellipses (...)** next to a guide and select **Share import link**. Toggle **Enable import link** on.
# Guides overview
Source: https://www.stedi.com/docs/edi-platform/guides
***
title: Guides overview
sidebarTitle: Guides overview
-----------------------------
EDI implementation guides define the format for a particular EDI transaction type. Stedi guides are a machine-readable version of the implementation guides your partners would typically provide to you as PDF, Word, or Excel files.
When you attach a guide to a [transaction setting](/edi-platform/configure/trading-partners/transaction-settings), Stedi uses it to validate and translate (inbound) or generate (outbound) the EDI files you exchange with your partner.
## Import pre-built guides
Stedi has thousands of pre-built guides for [X12 HIPAA](https://www.stedi.com/edi/network/hipaa) transactions and [popular retail and logistics partners](https://www.stedi.com/edi/network) that you can use in your integration. Once you find the guides you need, click **Import guide into your account** to add a copy to your Stedi account. Then, you can add the guide to any partnership's [transaction settings](/edi-platform/configure/trading-partners/transaction-settings#create-transaction-settings).
## View guides
You can view a list of all your guides on the **Guides** tab in your [Stedi account](https://portal.stedi.com/app).
# Public Guides
Source: https://www.stedi.com/docs/edi-platform/guides/public-guides
***
title: Public Guides
sidebarTitle: 'Share public guides'
-----------------------------------
Guides are private by default. Only members of your Stedi account can use private guides.
When you [make a guide public](#make-a-guide-public), your trading partners can view it as interactive web page and validate EDI documents against it instantly in their web browsers. Visit the [Stedi Network](https://www.stedi.com/edi/network) for examples.
When a guide is public, anyone with the link can:
* View the guide web page
* Print the guide
* Troubleshoot EDI files using the EDI Inspector.
## Make a guide public
To make a guide public, click the **ellipses (...)** next to the guide and select **Make public**. You can revert a public guide back to private at any time.
## Share public guide URL
After the guide is public, you can send its public URL to your trading partners and link to your guides from your own website. To copy a public guide's URL:
* Click the public guide to open it in the guide builder.
* Click **Actions**.
* Click the icon next to **View public guide** to copy the guide's public URL.
## Published guide settings
You can use **Published guide settings** to customize the appearance of your public guides. These settings apply to all published guides.
To change your published guide settings:
1. On the guides overview page, click **Published guide settings**.
2. You can adjust the following settings:
* **Logo:** If not specified, the guide displays your Stedi account name.
* **Company display name:** If not specified, the guide displays your Stedi account name.
* **URL slug**: If not specified, the slug is a hyphenated version of your account name.
* (Optional) **Include link:** If set to `ON`, you can add a custom link to the top of each public guide. For example, you may want to link to a particular page of your company's website.
* If you include a link, specify the **Link Label**, which is the button text for your custom link and the **Link url**.
# What is an EDI guide?
Source: https://www.stedi.com/docs/edi-platform/guides/what-is-a-stedi-guide
***
## title: What is an EDI guide?
You and your trading partner must agree on the exact format for each transaction type you plan to exchange. In practice, the larger trading partner typically dictates a format that the other trading partner must follow.
These requirements are defined in what the EDI industry calls an **implementation guide**, also known as a companion guide, EDI reference guide, or just a guide. An implementation guide is similar to a Schema definition, with a few peculiarities specific to EDI.
You need an implementation guide for each transaction type you plan to exchange with your partners. For example, you need an implementation guide for an 834 benefit enrollment and a separate guide for an 835 Electronic Remittance Advice (ERA).
## Validation
Implementation guides include information like expected fields, data types and sizes, and which fields are required. You can use these details to validate incoming and outgoing EDI documents.
## Stedi guides vs. standard guides
Standard EDI implementation guides are typically captured in a static format, like PDF, CSV, or even Word document files. In contrast, Stedi guides display EDI requirements as interactive web pages with built-in validation.
Stedi guides are also machine-readable, so Stedi can use them to read and write EDI documents according to each partner's EDI requirements. This is why we recommend always selecting a guide for each [transaction setting](/edi-platform/configure/trading-partners/transaction-settings) in your integration. When you attach a guide, Stedi uses it to validate and translate (inbound) or generate (outbound) the EDI transactions of that type.
Stedi has hundreds of Stedi guides for [X12 HIPAA transactions](https://www.stedi.com/edi/network/hipaa) and [popular retail and logistics trading partners](https://www.stedi.com/edi/network) that you can import into your Stedi account and use in your integration for free.
## Base specifications
All EDI implementation guides are customized versions of a base specification.
There are several EDI standards that provide base specifications. The most common are X12 and EDIFACT. The [EDI Reference](https://www.stedi.com/edi) documentation contains a full list of base specifications for each standard.
* [X12 transaction sets](https://www.stedi.com/edi/x12)
* [EDIFACT messages](https://www.stedi.com/edi/edifact)
A base specification is designed by a standard body to cover all possible use cases for a given transaction. For example, the base specification for ship notices contains fields for every type of ship notice you could ever encounter.
### X12 HIPAA in healthcare
In healthcare, HIPAA covered entities including most payers and providers are legally required to follow the CMS [adopted standard](https://www.cms.gov/priorities/key-initiatives/burden-reduction/administrative-simplification/hipaa/adopted-standards-operating-rules) X12 HIPAA implementation guides when creating transactions. X12 HIPAA is a narrower subset of the X12 standard. The official term for these specifications is a Technical Report Type 3 (TR3), but they are more commonly called X12 HIPAA implementation guides.
These official [X12 HIPAA implementation guides](https://www.stedi.com/edi/network/hipaa) are the ones you want to import into your Stedi account and use in your integration.
Many payers create companion guides for each transaction type, which act as an addendum to the X12 HIPAA implementation guides. For example, [Cigna](https://www.cigna.com/static/www-cigna-com/docs/5010-270-271-companion-guide.pdf), [Centers for Medicare and Medicaid Services](https://www.cms.gov/files/document/current-hets-270/271-companion-guide.pdf), and [UnitedHealthcare](https://www.uhcprovider.com/content/dam/provider/docs/public/resources/edi/EDI-270-271-Companion-Guide-005010X279A1.pdf) all have companion guides for 270/271 Eligibility/Benefit Inquiry and Response transactions (eligibility checks).
Companion guides help you understand the nuances of how each payer implements the X12 HIPAA standard. For example, a companion guide may specify how the payer indicates that a patient has a zero deductible for certain services.
### Implementation guides in logistics and retail
In the logistics and retail world, the existing base specifications for transactions like purchase orders and ship notices are far too generic for day-to-day use. Instead, you and your trading partner must agree on what that transaction set should contain and then adjust the base specification accordingly. The result is an implementation guide, which contains only a subset of [segments](https://www.stedi.com/edi/essentials/x12/segments) from the base specification.
Implementation guides can have other differences from the base specification as well. For example, some segments that are optional in the base specification may be marked as mandatory in the implementation guide.
Each trading partner has their own implementation guide for each type of transaction. For example, [Home Depot](https://portal.stedi.com/app/guides/view/home-depot/purchase-order/01H66G46HEFTS5NSV52VK41NZ2), [Walmart](https://portal.stedi.com/app/guides/view/walmart-edi/purchase-order-acknowledgment/01GNZA51CHFJJD9Y75GSSCXHHW), and [JCPenney](https://portal.stedi.com/app/guides/view/jcpenney/purchase-order-acknowledgment/01GV5KNNM3GAZHCEH5ZZ84XKTQ) all have separate implementation guides for the X12 850 Purchase Order.
These partner-specific implementation guides are the ones you want to import into your Stedi account and use in your integration.
# Mappings - Transform JSON
Source: https://www.stedi.com/docs/edi-platform/mappings
***
title: Mappings - Transform JSON
sidebarTitle: "Mappings overview"
---------------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
Integrating Stedi with your internal systems requires transforming Stedi [Guide JSON](/edi-platform/operate/transform-json/guide-json) to and from a format that your system can understand.
The Stedi Mappings module is a powerful JSON-to-JSON transformation engine. You can build mappings using Stedi’s visual mapper and use mappings to transform data for both inbound and outbound transactions.
For example, the following mapping transforms data from a translated 850 Purchase Order (Guide JSON) to the JSON Schema required for a simple Orders API endpoint.

## When to use Mappings
There are three ways you can transform Stedi transaction data (JSON) into a custom format: Stedi Mappings, writing custom code, and using an iPaaS platform. The approach you choose depends on your circumstances and preferences.
Mappings may be a good fit for your business when:
* Your system can natively produce and consume JSON payloads.
* You plan to do one-step transformations without multi-step processing.
* You want your business or operations team to manage mappings without engineering involvement.
* You want a solution that's integrated with the Stedi platform.
Visit our docs on [Transformation approaches](/edi-platform/operate/transform-json/transformation-approaches) for a detailed discussion of the pros and cons of each tranformation method.
### Read EDI
The most common Mappings use case is transforming processed transaction data from Stedi into a custom JSON Schema for your business system.
You can use [webhooks](/edi-platform/configure/webhooks) to automatically send transaction processed events to any API endpoint. Then, you can use the [Map Transaction Output](/api-reference/edi-platform/get-map-transaction-output) endpoint to return the mapped output of the processed inbound transaction.
### Write EDI
You can also use Mappings to transform JSON from your business systems into the [Guide JSON](/edi-platform/operate/transform-json/guide-json) format required to Stedi's API.
### Ingest Stedi events
You may want to transform [Stedi events](/edi-platform/operate/event-types) into a custom shape before sending them to your business system. For example, you may want to ingest `file.failed.v2` events into applications like Slack or Zapier to create internal alerts for your operations team.
# Mappings limits
Source: https://www.stedi.com/docs/edi-platform/mappings/limits
***
title: Mappings limits
sidebarTitle: 'Limits'
description: ''
---------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
The following service limits are configured across Mappings APIs, except where otherwise indicated. If you are impacted or blocked by any of these restrictions, please let us know and we would be happy to help meet your needs.
| Resource or operation | Limit | Can be increased |
| --------------------------------------- | --------- | ---------------- |
| Maximum number of mappings per account | 1,000 | Yes |
| Requests per second\* | 1,000 | Yes |
| Requests per day | 1,000,000 | Yes |
| Mapping source JSON Schema | 300 KB | No |
| Mapping target JSON Schema | 300 KB | No |
| Mapping JSONata expression | 300 KB | No |
| Lookup tables combined size | 300 KB | No |
| Maximum mapped document size | 4 MB | No |
| Maximum mapping operation response size | 4 MB | No |
| Maximum mapping operation duration | 7 seconds | Yes |
| Maximum input payload size | 6 MiB | No |
*\* The rate limit for the List Mappings endpoint is 25 requests per second.*
# Invoke mappings
Source: https://www.stedi.com/docs/edi-platform/mappings/transform-json-documents
***
title: Invoke mappings
sidebarTitle: 'Invoke'
----------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
Once you [create a mapping](/edi-platform/mappings/manage-mappings/ui-guide), you can use it to transform JSON into a custom shape.
## Inbound - Mappings API
You can use webhooks to automatically send transaction processed events to any API endpoint. Then, you can use the [Map Transaction Output](/api-reference/edi-platform/get-map-transaction-output) endpoint to return the mapped output of the processed inbound transaction.
You can also call the [Invoke Mapping API](/api-reference/edi-platform/post-invoke-mapping) to transform JSON into a custom shape.
## Outbound - Create Outbound Transaction
Call the [Create Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint with a mapping ID. Stedi uses the specified mapping to automatically transform your system’s data into Guide JSON before generating and delivering the EDI file.
### Payload validation
By default, the Mappings API doesn't validate incoming or transformed JSON.
When you enable **strict validation mode**, Mappings uses the [source schema](/edi-platform/mappings/manage-mappings/mapping-definition#source-schema)
to validate the input JSON payload and the [target schema](/edi-platform/mappings/manage-mappings/mapping-definition#target-schema)
to validate the outgoing JSON payload.
To enable strict validation mode, set the `validation_mode` query parameter to `strict`. The following example shows how to enable strict validation mode in your request.
```http
POST https://mappings.us.stedi.com/2021-06-01/mappings/01AB3DEF4GHIJ5KL67MNOP8QR9/map?validation_mode=strict HTTP/1.1
```
**Success and failure responses**
* If the mapping is evaluated successfully and there are no validation failures, the body of the response is the mapped document.
* If the evaluation of the mapping expression fails, then validation of the input and the output is not applied, the response is a 400 error with the `mapping_failed` code and no `validation_errors` object.
* If validation of the input or output payload fails, the response is a 400 error with the `validation_failed` code and `validation_errors` object.
### Example request
The following example shows a request to the [Invoke Mapping API](/api-reference/edi-platform/post-invoke-mapping). The request body is the JSON document that you want to map.
```http
POST https://mappings.us.stedi.com/2021-06-01/mappings/01AB3DEF4GHIJ5KL67MNOP8QR9/map HTTP/1.1
"Authorization: ${STEDI_API_KEY}"
Content-Type: application/json
{
"quantity": 15,
"unit_price": 2.50
}
```
The body of the response is the mapped document.
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"total": 37.50
}
```
You must make a separate request to the API for each JSON document. Visit
[Concurrency](#api-concurrency) for more details.
## Send a compressed payload to the API
To send a `gzip` compressed payload to the Mappings API, set the `Content-Encoding` header to the value of `gzip`. Mappings API currently only supports `gzip` compression.
Note that the [maximum document size limit](/edi-platform/mappings/limits) **is applied after decompressing the content of the payload**. If the decompressed payload of a given request is larger than the maximum document size limit, the Mappings API will reject the request.
The following is an example written in [TypeScript](https://www.typescriptlang.org/) of creating mapping and sending a `gzip` compressed payload to the `/map` endpoint.
```ts
import axios from 'axios';
import { gzipSync } from 'zlib';
const STEDI_API_KEY = 'YOUR_API_KEY';
const rootURL = 'https://mappings.us.stedi.com/2021-06-01/mappings';
const headers = { Authorization: `Key ${STEDI_API_KEY}` };
async function doRequest() {
const mapping = {
name: 'GzipPayloadMapping',
mapping: `{"Hello": keyFromSource}`,
type: 'only_mapped_keys',
};
const createMappingResponse = await axios.post(rootURL, mapping, { headers });
const payload = gzipSync(JSON.stringify({ keyFromSource: 'World!' }));
const mapResponse = await axios.post(
`${rootURL}/${createMappingResponse.data.id}/map`,
payload,
{
headers: {
...headers,
'Content-Encoding': 'gzip',
},
},
);
console.log(mapResponse.data);
}
async function main() {
try {
await doRequest();
} catch (e) {
console.log(e);
}
}
main();
```
## API concurrency
Mappings allows up to 200 concurrent requests, so if you need to map 200 documents or less, you can send them all at once. If you need to map more than 200 documents, you should make sure that you don't exceed 1000 requests per second. Also keep in mind that there's a maximum of one million requests per day.
If you make more requests than Mappings is able to handle, you will receive a `429 Too Many Requests` response.
* Keep track of how many outstanding requests you have. Don't send any new requests if you have 200 or more.
* Keep track of how many total requests you've sent in a day and make sure it doesn't exceed 1,000,000.
* Keep a timestamp for every successful response you receive. When sending a new request, first check the timestamp for 1000 requests ago. If it's less than a second ago, wait until the second has passed before making a new request.
* If you receive a 429 Too Many Requests response, wait for one second before sending new requests. If you still get back 429 after waiting for one second, then wait for two seconds. If that's not enough wait for four, then eight, etc.
* If you receive a 429 Too Many Requests response, add the document back into the list of documents that you need to map. Don't resend the request immediately.
# Events types and structure
Source: https://www.stedi.com/docs/edi-platform/operate/event-types
***
title: Events types and structure
sidebarTitle: Events
description: ""
---------------
Stedi emits events as it processes and generates EDI files. You can use these events to trigger [webhooks](/edi-platform/configure/webhooks), trigger alerts in systems like Slack or PagerDuty, and implement more advanced functionality.
## Event types
Stedi emits the following types of events.
### Transaction processed
The `transaction.processed.v2` event is the primary integration point for transactions you receive from your trading partner. Stedi emits one `transaction.processed.v2` event for every transaction successfully processed.
Since an EDI file can contain multiple transactions, a single EDI file can result in multiple `transaction.processed.v2` events.
```json webhook
{
"event": {
"version": "0",
"id": "65409ec4-6d2d-dc87-43e2-3b31ff49d2da",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2025-05-06T19:35:08Z",
"region": "us-east-1",
"resources": [],
"detail": {
"transactionId": "d303ce95-7533-4f18-916d-51b7e446c364",
"direction": "INBOUND",
"mode": "test",
"fileExecutionId": "e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9",
"processedAt": "2025-05-05T20:14:55.809Z",
"fragments": null,
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"url": "https://core.us.stedi.com/2023-08-01/transactions/d303ce95-7533-4f18-916d-51b7e446c364/input",
"sizeBytes": 1077,
"model": "transaction"
},
{
"artifactType": "application/json",
"usage": "output",
"url": "https://core.us.stedi.com/2023-08-01/transactions/d303ce95-7533-4f18-916d-51b7e446c364/output",
"sizeBytes": 5118,
"model": "transaction"
}
],
"partnership": {
"partnershipId": "local-clearinghouse-test",
"partnershipType": "x12",
"sender": {
"profileId": "clearinghouse-test"
},
"receiver": {
"profileId": "local"
}
},
"x12": {
"transactionSetting": {
"guideId": "01JJ49X7R37FQ7WP29WWMQ0N6A",
"transactionSettingId": "01JA95YJZ68VGHAZV2ET0AZW44"
},
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "0",
"controlNumber": 194
},
"functionalGroup": {
"controlNumber": 194,
"release": "005010X214",
"date": "2025-05-05",
"time": "20:14:19",
"functionalIdentifierCode": "HN"
},
"transaction": {
"controlNumber": "1001",
"transactionSetIdentifier": "277"
},
"receiver": {
"applicationCode": "524147114425",
"isa": {
"qualifier": "ZZ",
"id": "524147114425"
}
},
"sender": {
"applicationCode": "STEDITEST",
"isa": {
"qualifier": "ZZ",
"id": "STEDITEST"
}
}
}
},
"connectionId": "01JA95YP8E885W00E6SAJDWGHS"
}
}
}
```
When [fragments](/edi-platform/fragments) are enabled on the transaction, Stedi emits one `transaction.processed.v2` event and one `fragment.processed.v2` event for each fragment.
#### Retrieve transaction data
You can use the `documentDownloadUrl` URLs in the `event.detail.artifacts` objects to fetch transaction data from Stedi.
* Use the URL in the artifact with `"usage": "input"` to fetch the input for the transaction. For inbound transactions, this is the EDI you received from your trading partner.
* Use the URL in the artifact with `"usage": "output"` to fetch the output for the transaction. For inbound transactions, this is processed transaction data in [Guide JSON](/edi-platform/operate/transform-json/guide-json) format.
To retrieve transaction data, make a request with the URL and your Stedi API key for authorization.
If your HTTP library automatically follows redirects, you will receive the transaction data in the response body. If it does not follow redirects, the response includes a `documentDownloadUrl` that you can use to retrieve the transaction data.
The following example shows a cURL request to retrieve transaction data. This example uses the `-L` option for following redirects.
```bash
curl -L -H "Authorization: ${STEDI_API_KEY}" \
https://core.us.stedi.com/2023-08-01/transactions/$TRANSACTION_ID/output
```
### Fragment processed
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
You can use [fragments](/edi-platform/fragments) to split transaction payloads into smaller chunks for easier downstream processing. By default, a single fragment will include a maximum of 800 repeated segments. You can customize the batch size when creating the [transaction setting](/edi-platform/configure/trading-partners/transaction-settings#create-transaction-settings).
Stedi emits one `fragment.processed.v2` event for each fragment within a processed transaction. The payload contains details about the original transaction, including the `ISA` and `GS` headers. These details about the original transaction are included in every fragment event.
```json Fragment with data
{
"event": {
"version": "0",
"id": "1c0872a3-dfcc-4b63-9ce7-08ce9ebd9170",
"detail-type": "fragment.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2023-11-13T15:47:09Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/transactions/1b1d2424-72ba-4157-bcfa-3e1620430a3f"
],
"detail": {
"fileExecutionId": "bb141a6f-79f8-9c88-9b91-37609ddd90f9",
"transactionId": "1b1d2424-72ba-4157-bcfa-3e1620430a3f",
"direction": "INBOUND",
"mode": "production",
"processedAt": "2023-11-13T15:47:09.231Z",
"fragments": {
"batchSize": 800,
"fragmentCount": 1,
"keyName": "item_identification_LIN_loop"
},
"fragmentIndex": 0,
"artifacts": [
{
"artifactType": "application/json",
"usage": "output",
"url": "https://core.us.stedi.com/2023-08-01/transactions/1b1d2424-72ba-4157-bcfa-3e1620430a3f/fragments/0/output",
"model": "fragment",
"sizeBytes": 4802
}
],
"partnership": {
"partnershipId": "wormpotato_amazonds",
"partnershipType": "x12",
"sender": { "profileId": "amazonds" },
"receiver": { "profileId": "wormpotato" }
},
"x12": {
"transactionSetting": {
"guideId": "01H9JMMG4839VQG9QQVSZ6X29G",
"transactionSettingId": "01HF4N77F5YWA2RXEDMMF5FF6J"
},
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "0",
"controlNumber": 76
},
"functionalGroup": {
"controlNumber": 76,
"release": "004010",
"date": "2022-09-24",
"time": "20:01",
"functionalIdentifierCode": "IB"
},
"transaction": {
"controlNumber": "319101",
"transactionSetIdentifier": "846"
},
"receiver": {
"applicationCode": "ACME",
"isa": { "qualifier": "ZZ", "id": "WORMPOTATO" }
},
"sender": {
"applicationCode": "SENDERID",
"isa": { "qualifier": "ZZ", "id": "AMAZONDS" }
}
}
}
}
}
}
```
#### Retrieve transaction data
The following example shows a cURL request to retrieve details about the fragment associated with a transaction. This example uses the `-L` option for following redirects.
```
curl -L -H "Authorization: ${STEDI_API_KEY}" \
'https://core.us.stedi.com/2023-08-01/transactions/$TRANSACTION_ID/edi-platform/fragments/$FRAGMENT_INDEX/output'
```
### File processed
You may want to consume `file.processed.v2` events when you want to route non-EDI files that arrive on Stedi for additional processing.
Stedi emits a `file.processed.v2` event for all successful file executions. You can view details on the [Files](https://portal.stedi.com/app/core/file-executions) page.
For files with the following extensions, Stedi emits a `file.processed.v2` event but does not attempt to parse them as EDI: `.json`, `.csv`, `.xml`, `.xls`, `.xlsx` or `.pdf`.
```json file.processed.v2 event
{
"event": {
"version": "0",
"id": "84923a9b-5881-bd5b-5b7b-9f0461d0802f",
"detail-type": "file.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2025-05-06T19:35:22Z",
"region": "us-east-1",
"resources": [],
"detail": {
"fileExecutionId": "e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9",
"processedAt": "2025-05-05T20:14:56.038Z",
"partnershipId": "local-clearinghouse-test",
"connectionId": "01JA95YP8E885W00E6SAJDWGHS",
"source": {
"dirname": "clearinghouse/incoming",
"name": "9d7c38f4-410b-4032-aad4-016d8140b265.x12"
},
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"sizeBytes": 1270,
"url": "https://core.us.stedi.com/2023-08-01/executions/e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9/input",
"model": "execution"
},
{
"artifactType": "application/json",
"usage": "metadata",
"url": "https://core.us.stedi.com/2023-08-01/executions/e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9/metadata",
"model": "execution",
"sizeBytes": 2532
}
]
}
}
}
```
### File delivered
Stedi emits the `file.delivered.v2` event every time a file is successfully delivered to a [connection](/edi-platform/configure/trading-partners/connections) for an outbound transaction set. This event is only emitted for generated EDI (outbound) files and is not emitted for inbound files.
```json file.delivered.v2 event
{
"event": {
"version": "0",
"id": "3fb45b5f-bd7f-f9d0-c0a2-84946f20a9da",
"detail-type": "file.delivered.v2",
"source": "stedi.core",
"account": "",
"time": "2025-05-06T19:35:17Z",
"region": "us-east-1",
"resources": [],
"detail": {
"fileExecutionId": "e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9",
"processedAt": "2025-05-05T20:14:57.882927984Z",
"artifacts": [
{
"artifactType": "application/edi-x12",
"usage": "input",
"sizeBytes": 1270,
"url": "https://core.us.stedi.com/2023-08-01/executions/e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9/input",
"model": "execution"
},
{
"artifactType": "application/edi-x12",
"usage": "output",
"sizeBytes": 1270,
"url": "https://core.us.stedi.com/2023-08-01/executions/e181c2ab-f85c-42bd-9cda-a7bd1e32b4c9/output",
"model": "execution"
}
],
"connection": {
"connectionType": "STEDI_ACCOUNT_FTP",
"connectionId": "01JM0XF37DXZ3THZ7N75YJTW52"
},
"delivery": {
"status": "DELIVERED",
"message": "Delivered to 'Test Account SFTP'",
"artifactId": "9d7c38f4-410b-4032-aad4-016d8140b265.x12"
}
}
}
}
```
#### Retrieve execution data
Both the `file.delivered.v2` and `file.processed.v2` events include URLs in the `event.detail.artifacts` objects you can use to fetch execution data from Stedi.
* The URL for the `input` artifact allows you to retrieve the input to Stedi. For `file.processed.v2` events, this option is helpful when you want to react to and handle non-X12 inbound files flowing through Stedi, such as CSV, TSV, XML, and PDF files.
* The URL for the `output` artifact allows you to retrieve the output from Stedi. For `file.delivered.v2` events, this option retrieves the entire generated EDI file (including the envelope information) that Stedi delivered to your trading partner.
* The URL for the `metadata` artifact (`file.processed.v2` only) allows you to retrieve the execution metadata from Stedi, which includes the processing date and time, the control number, and other information about the file.
```json Example X12 metadata response
{
"version": "2024-01-01",
"interchanges": [
{
"envelope": {
"senderQualifier": "ZZ",
"senderId": "STEDITEST",
"receiverQualifier": "ZZ",
"receiverId": "111222333444555",
"date": "2025-02-12",
"time": "22:20",
"versionNumberCode": "00501",
"controlNumber": 11,
"acknowledgmentRequestedCode": "0",
"usageIndicatorCode": "T",
"trailer": {
"numberOfIncludedFunctionalGroups": 1,
"controlNumber": 11
},
"segments": {
"isa": "ISA*00* *00* *ZZ*STEDITEST *ZZ*111222333444555 *250212*2220*^*00501*000000011*0*T*:",
"iea": "IEA*1*000000011"
}
},
"acknowledgments": [],
"standard": "x12",
"span": {
"start": 0,
"end": 941
},
"delimiters": {
"segment": "~",
"element": "*",
"composite": ":",
"repetition": "^"
},
"functionalGroups": [
{
"envelope": {
"functionalIdentifierCode": "HN",
"applicationSenderCode": "STEDITEST",
"applicationReceiverCode": "111222333444555",
"date": "2025-02-12",
"time": "22:20:43",
"controlNumber": 11,
"responsibleAgencyCode": "X",
"release": "005010X214",
"trailer": {
"numberOfIncludedTransactionSets": 1,
"controlNumber": 11
},
"segments": {
"gs": "GS*HN*STEDITEST*111222333444555*20250212*222043*11*X*005010X214",
"ge": "GE*1*11"
}
},
"span": {
"start": 106,
"end": 925
},
"transactionSets": [
{
"id": "277",
"controlNumber": "1001",
"implementationConventionReference": "005010X214",
"trailer": {
"numberOfIncludedSegments": 26,
"controlNumber": "1001"
},
"span": {
"start": 167,
"end": 917
},
"trackedIdentifiers": {
"BHT-03": [
"181135085"
],
"TRN-02": [
"20250212170508224",
"12341234",
"0",
"01J99GTR3J1X4C303BCMEX2KSZ"
]
}
}
]
}
]
}
]
}
```
To retrieve execution data, make a request with the URL and your Stedi API key for authorization.
If your HTTP library automatically follows redirects, you will receive the execution input data in the response body. If it does not follow redirects, the response includes a `documentDownloadUrl` that you can use to retrieve the transaction data.
The following example shows a cURL request to retrieve execution data. This example uses the `-L` option for following redirects.
```bash
curl -L -H "Authorization: ${STEDI_API_KEY}" \
https://core.us.stedi.com/2023-08-01/executions/$EXECUTION_ID/input
```
### File failed
Stedi emits `file.failed.v2` events in two scenarios:
* When a failure occurs while processing an inbound file. Stedi emits the `file.failed.v2` event at the file level. If a single transaction set fails, the entire file fails.
* When an outbound file cannot be delivered to a configured connection.
{" "}
Stedi attempts to deliver a file to all configured connections every 6 minutes for up to 3 total attempts. If it cannot deliver the file after the third attempt, it marks the file execution as `FAILED` and emits the [`file.failed.v2` event](/edi-platform/operate/event-types#file-failed). Stedi displays each delivery attempt and the failure details on the [Files](https://portal.stedi.com/app/core/file-executions) page.
```json file failed event
{
"event": {
"version": "0",
"id": "cef43062-0258-cbac-b06d-ec6a21f03c69",
"detail-type": "file.failed.v2",
"source": "stedi.core",
"account": "",
"time": "2025-06-05T11:26:16Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/executions/7590afcd-26d7-4182-a8fc-1d1051e2815c"
],
"detail": {
"fileExecutionId": "7590afcd-26d7-4182-a8fc-1d1051e2815c",
"direction": "INBOUND",
"processedAt": "2025-06-05T11:26:16.354Z",
"source": {
"dirname": "remote-ftp/test/01JJYJ0GGVZD5GR230YP6G3MEA/fromPartner",
"name": "Test_Dental.1234567.835"
},
"artifacts": [
{
"artifactType": "application/edi-x12",
"url": "https://core.us.stedi.com/2023-08-01/executions/7590afcd-26d7-4182-a8fc-1d1051e2815c/input",
"usage": "input",
"model": "execution"
}
],
"connectionId": "01JJYJ0GGVZD5GR230YP6G3MEA",
"partnership": {
"partnershipId": "stedi-test_dentalpartner",
"partnershipType": "x12",
"receiver": {
"profileId": "stedi-test"
},
"sender": {
"profileId": "dentalpartner"
}
},
"errors": [
{
"message": "String element BPR-10 must have a length of 10, actual length is 5\nElement PER-02 is not used by this guide",
"faultCode": "FAILED_TO_TRANSLATE"
}
],
"x12": {
"metadata": {
"interchange": {
"acknowledgmentRequestedCode": "1",
"controlNumber": 56199839
}
},
"receiver": {
"isa": {
"qualifier": "30",
"id": "117151744"
}
},
"sender": {
"isa": {
"qualifier": "ZZ",
"id": "900117186"
}
}
}
}
}
}
```
## Retry events
You can retrigger file processing events for successfully processed files. This feature makes it easier to test your end-to-end integration – for example, triggering webhooks – without continually reprocessing the same files.
To retry an event:
1. Go to the [Files](https://portal.stedi.com/app/core/file-executions) page.
2. Click the name of the processed file.
3. Go to the **Events** tab.
4. Click the **ellipses (...)** next to an event and select **Retry**.
## When are events emitted?
Stedi emits events in the following scenarios.
### An entire file has successfully processed
Consider an EDI file that contains two functional groups, and a total of three transaction sets. When Stedi successfully processes all transaction sets, it generates the following events:
* 1x `file.processed.v2` - indicating the entire file was processed successfully.
* 3x `transaction.processed.v2` - one event for each transaction set found in both groups.

### At least one transaction fails to validate
If one or more transaction sets in a file fails validation, Stedi emits a single `file.failed.v2` error, indicating that one or more transactions failed to process. Stedi cannot process the entire file until you address those issues.

## Event structure
All Stedi events follow a standard JSON Schema. The event payload itself does not include the contents of a given file or transaction. Instead, it references an API path to retrieve the entire object.
```json JSON event structure example
{
"version": "0",
"id": "8a9fc08a-24b2-4eeb-af7c-f96376ea471e",
"detail-type": "transaction.processed.v2",
"source": "stedi.core",
"account": "",
"time": "2021-11-12T00:00:00Z",
"region": "us-east-1",
"resources": [
"https://core.us.stedi.com/2023-08-01/transactions/3543b3f7-0d78-48cc-97c3-ac145e250a1d"
],
"detail": { ... }
}
```
In addition to their `version`, `id`, and `time`, events have the following properties:
* **`detail-type`** - Indicates the type of event, such as `transaction.processed.v2` or `file.failed.v2`.
* **`source`** - Indicates the component that generated the event. All events use `source: “stedi.core”`.
* **`account`** - The account ID that generated the event.
* **`region`** - The AWS region where the event was generated.
* **`resources`** - The URL to the resource that Stedi created. This could be a transaction or a file execution, depending on the event type. Hitting the URL with your API key is equivalent to calling the [Get Execution](/api-reference/edi-platform/core/get-executions) and [Get Transaction](/api-reference/edi-platform/core/get-transactions) endpoints.
* **`detail`** - The JSON payload. The schema for each payload is determined by the `detail-type`.
# Failures and retries
Source: https://www.stedi.com/docs/edi-platform/operate/failures-and-retries
***
title: Failures and retries
sidebarTitle: 'Failures and retries'
------------------------------------
When Stedi encounters EDI processing failures, it displays them on the **Files** page and emits a [file.failed.v2](/edi-platform/operate/event-types#file-failed) event.
## Inbound EDI
When Stedi ingests EDI, it must first match the data to a [partnership](/edi-platform/configure/trading-partners/profiles-and-partnerships) and then validate the incoming EDI according to the partnership configuration. Failures may occur when the file does not contain sufficient heading data to match transactions to an existing partnership or when the incoming file contains invalid EDI.
Core only marks an incoming file as successfully processed when all the individual transaction sets within the file are valid against either the guide or the base X12 specification. If one transaction set is invalid, Stedi flags the entire file as failed.
Other processing failures may occur occasionally, most commonly for missing configuration or misconfigured data. Failure causes include:
* Stedi cannot find a profile record matching the `ISA` headers.
* Stedi cannot find a partnership record defined for the two profiles detected.
* Stedi received a corrupt or unparseable file.
## Outbound EDI
The Generate API uses a [Stedi guide](/edi-platform/guides) and other partnership settings to generate valid EDI with the proper envelope and control numbers. Failures may occur when tries to deliver the file to a configured [connection](/edi-platform/configure/trading-partners/connections).
After generating EDI, Stedi marks the file as successfully processed after delivering it to all configured connections. Stedi does not display transactions from within files that have failed delivery.
Stedi attempts to deliver a file to all configured connections every 6 minutes for up to 3 total attempts. If it cannot deliver the file after the third attempt, it marks the file execution as `FAILED` and emits the [`file.failed.v2` event](/edi-platform/operate/event-types#file-failed). Stedi displays each delivery attempt and the failure details on the [Files](https://portal.stedi.com/app/core/file-executions) page.
## Ignore failed files
Ignoring a failed file changes its status to **Ignored** and removes it from your list of failed files. You can bulk retry ignored files at any time or use filters to remove them from your dashboard view.
To ignore failed files individually:
1. Go to the [Files](https://portal.stedi.com/app/core/file-executions) page and click the name of the file you want to ignore.
2. Click **Ignore**.
To bulk ignore multiple failed files:
1. Go to the [Files](https://portal.stedi.com/app/core/file-executions) page.
2. Filter the list to the failed files you want to ignore.
3. Click **Bulk actions** and select **Bulk ignore**.
## Retry files
To retry failed files individually:
1. Go to the [Files](https://portal.stedi.com/app/core/file-executions) page and click the name of the file you want to retry.
2. Click **Retry**.
To bulk retry all failed files:
1. Go to the [Files](https://portal.stedi.com/app/core/file-executions) page.
2. Filter the list to show only failed files.
3. Click **Bulk actions** and select **Bulk retry**.
## Retry events
You can retrigger events for successfully processed files. This feature makes it easier to test your end-to-end integration – for example, triggering webhooks – without continually reprocessing the same files.
To retry an event:
1. Go to the [Files](https://portal.stedi.com/app/core/file-executions) page and click the name of the processed file.
2. Go to the **Events** tab.
3. Click the **ellipses (...)** next to an event and select **Retry**.
## Diagnosing failures
Stedi displays all of the events associated with each file execution and transaction in the dashboard. You can use this information to quickly debug issues and understand how your data flows through Stedi. Visit [Monitor transactions](/edi-platform/operate/transaction-data#manage-failed-files) for details.
# File processing overview
Source: https://www.stedi.com/docs/edi-platform/operate/file-processing-overview
***
title: File processing overview
sidebarTitle: "File processing overview"
----------------------------------------

Once you [add a trading partner](/edi-platform/configure), you can start exchanging EDI files.
## Inbound processing flow
When a new EDI file arrives over a [connection](/edi-platform/configure/trading-partners/connections), Stedi automatically:
1. Confirms that the information in the file's `ISA` headers matches the corresponding partnership. If not, the file will error, and you can retry after creating the required configuration. (Stedi may skip this step if the connection is set to a non-default [**ISA validation** option](/edi-platform/configure/trading-partners/connections#isa-validation-options).)
2. Identifies all available transaction sets in the file and validates them against the [transaction settings](/edi-platform/configure/trading-partners/transaction-settings) for the partnership, either using the specified guide or the base X12 specification.
3. Translates the EDI transaction into [Guide JSON](/edi-platform/operate/transform-json/guide-json), using the JSON Schema defined by the guide.
4. Sends processing events to any configured [webhooks](/edi-platform/configure/webhooks).
5. Persists the original EDI file and the Guide JSON for review and retrieval and displays the transaction set data in the UI for inspection.
Stedi can also route non-EDI files, such as CSV, XML, and JSON to your
business system for further processing. [Learn
more](/edi-platform/operate/parse-edi#non-edi-file-types)
## Outbound processing flow
When you use the API to generate EDI files, Stedi automatically:
1. Validates the [Guide JSON](/edi-platform/operate/transform-json/guide-json) transaction payload against the guide attached to the [outbound transaction setting](/edi-platform/configure/trading-partners/transaction-settings) for the partnership. The API returns an error if validation is not successful.
2. Generates an EDI document that conforms to outbound transaction setting.
3. Persists the JSON payload and resulting EDI file.
4. Delivers the EDI file to your trading partner through the configured connection.
5. Displays the generated file on the **Files** page in the Stedi portal for review.
6. Emits a `file.delivered.v2` event and one or more `transaction.processed.v2` [events](/edi-platform/operate/event-types).
# Generate test files in your browser
Source: https://www.stedi.com/docs/edi-platform/operate/generate-test-files
***
title: Generate test files in your browser
sidebarTitle: "Generate test files"
-----------------------------------
You can generate and process inbound and outbound test files to simulate exchanging files with your trading partner.
You can review generated test files on the [Files](https://portal.stedi.com/app/core/file-executions) page and all processed transactions on the [Transactions](https://portal.stedi.com/app/core/transactions) page.
## Inbound test files
Generating an inbound test file triggers any configured [webhooks](/edi-platform/configure/webhooks), so this is a great method for testing your entire inbound EDI processing flow.
To generate and send an inbound test file:
1. Do one of the following:
* Go to the [Files](https://portal.stedi.com/app/core/file-executions) page.
* Go to the [Trading partners](https://portal.stedi.com/app/core/partnerships) page, click a partnership, and go to its inbound transaction settings.
2. Click **Test inbound**.
3. Select a **Partnership** and an **Inbound transaction setting**.
4. Edit the **Transaction payload** to include realistic or actual data from your system. The payload editor validates your data as you change it.
* If the guide associated with this transaction setting has sample files, you can choose a **Sample** and load its data into the editor.
5. Click **Ingest file**.
Stedi immediately begins processing the file. The processed file will trigger any configured webhook.
## Outbound test files
Outbound test files contain a `T` in the `Usage` element of the `ISA` header. This indicates that the file is a test file and should not be processed by your trading partner's production system. Sometimes, your trading partner will provide you with a dedicated test SFTP/FTPS or AS2 connection. If they have done so, be sure to assign the test connection to your outbound transaction setting.
To generate and send an outbound file:
1. Do one of the following:
* Go to the [Files](https://portal.stedi.com/app/core/file-executions) page.
* Go to the [Trading partners](https://portal.stedi.com/app/core/partnerships) page, click a partnership, and go to its outbound transaction settings.
2. Click **Test outbound**.
3. Select a **Partnership** and an **Outbound transaction setting**.
4. (Optional) Set **Advanced settings**. For example, you may want to set a **Filename** if your trading partner has specific requirements for the file name. If you do not specify a filename, Stedi generates a unique file name using a UUID.
5. Edit the **Transaction payload** to include realistic or actual data from your system. The payload editor validates your data as you change it.
* If the guide associated with this transaction setting has sample files, you can choose a **Sample** and load its data into the editor.
6. Click **Continue** and then click **Send EDI**.
Stedi immediately begins generating the test file and sends it to your trading partner over the configured connection.
# Parse EDI
Source: https://www.stedi.com/docs/edi-platform/operate/parse-edi
***
title: Parse EDI
sidebarTitle: "Parse EDI"
-------------------------
Stedi automatically validates and parses inbound EDI files in real time, according to the [transaction settings](/edi-platform/configure/trading-partners/transaction-settings) you defined for the trading partner.
## Files with multiple EDI interchanges
Stedi can process files containing multiple EDI interchanges. However, you may need to update the connection's [**ISA validation options**](/edi-platform/configure/trading-partners/connections#isa-validation-options) depending on the expected `ISA` values:
* If every `ISA` header will have the same sender and receiver IDs, you can leave the connection on the **Default** option.
* If the `ISA` headers could have multiple different sender and receiver IDs, you must set the connection to **Ignore ISA validation**. This option makes it harder to troubleshoot issues in your account, so we recommend only using it if you're very sure you need it for your use case.
Stedi emits a `file.processed.v2` event for the file and one `transaction.processed.v2` event for each transaction within the file.
You can review each processed interchange on the file's details page in the Stedi portal.
## Send transactions to your business system
You can use [webhooks](/edi-platform/configure/webhooks) to automatically send `transaction.processed.v2` events to any API endpoint. The [`transaction.processed.v2` event](/edi-platform/operate/event-types#event-types) contains a URL that you can then use to fetch processed transaction data from Stedi.
## Transform transactions to a custom shape
Stedi translates EDI files into [Guide JSON](/edi-platform/operate/transform-json/guide-json), a JSON format that closely reflects the structure of an EDI transaction. You need to transform Guide JSON into a shape your system can understand and ingest.
Visit [Transformation approaches](/edi-platform/operate/transform-json/transformation-approaches) for details.
## Large file support
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
If you need to process EDI files over 10 MB in size, we recommend adding the Large file processing module. [Contact us](https://www.stedi.com/contact) for details.
You may also want to use [Fragments](/edi-platform/fragments), a module that helps you split processed transactions from Stedi into smaller chunks for downstream ingestion.
## Non-EDI file types
Stedi can route non-EDI formats like CSV, JSON, and XML for further processing.
When a non-EDI file arrives, the file appears in the UI, and Stedi emits an event that contains a summary of the file execution. You can configure webhooks that forward this event to your business system.
How Stedi processes non-EDI files depends on the file extension:
* Stedi emits a [`file.processed.v2` event](/edi-platform/operate/event-types#file-processed) for all files with `.json`, `.csv`, `.xml`, `.xls`, `.xlsx` or `.pdf` file extensions.
* Stedi attempts to process any other file extension, such as .`txt` or `.edi`, as EDI. If parsing fails, it attempts to parse the file first as JSON and then as CSV. If parsing still fails, it will mark the execution as failed and emit a [`file.failed.v2` event](/edi-platform/operate/event-types#file-failed), which can be used to trigger additional processing.
## Processing limits
Stedi can process EDI files that are gigabytes in size, and there is no hard restriction on the maximum file size you can attempt to process. If you run into issues processing a large file, please [reach out](https://www.stedi.com/contact) and our engineers will help remove any limitations that you're encountering.
# Monitor transactions
Source: https://www.stedi.com/docs/edi-platform/operate/transaction-data
***
title: Monitor transactions
sidebarTitle: 'Monitor transactions'
------------------------------------
You can monitor, inspect, test, and debug the transaction data flowing through Stedi.
## Filter and sort
You can review all incoming and outgoing transaction data on the [**Files**](https://portal.stedi.com/app/core/file-executions) and [**Transactions**](https://portal.stedi.com/app/core/transactions) pages.
### Files
Each file sent or received can contain multiple transactions. The [Files](https://portal.stedi.com/app/core/file-executions) page shows every file you have exchanged with trading partners, its processing status, and the number of transactions within the file.
You can filter files by various attributes, including status (such as `Failed` or `Completed`), direction, partnership, and fault (such as `failed to find guide`).
### Transactions
Individual [**Transactions**](https://portal.stedi.com/app/core/transactions) only appear after an entire file has been successfully processed. Every transaction that has been successfully sent to or received from your trading partners appears in this list.
You can filter transactions by various attributes, including transaction set, sender, receiver, direction, and usage (such as `production` or `test`). You can also search for specific transaction sets based on a business identifier, such as a purchase order number.
## Inspect raw data
You can review the raw EDI or JSON data for processed files and individual transactions. Click the name of the file or transaction to review its data.
### View a file execution
The file execution detail page contains processing results and the entire source of the original, unmodified file. You can copy or download the source file to your local machine.
### View a transaction
The transaction detail page includes two tabs that display different levels of information.
* **Details:** Displays metadata about the transaction, including the sender, receiver, the guide used for validation, and more.
* **Inspector:** Shows the transaction payload in a human-friendly view, which you can use to understand the contents of the transaction.
You can also view and download the raw EDI or JSON data for a transaction.
**Advanced EDI users:** When viewing the raw EDI for a single transaction, the
transaction EDI view includes the `ISA` (Interchange Control Header) and `GS`
(Functional Group Header) from the source file. However, it does not include
any other transaction sets that were in the source file, so the segment counts
may not total correctly.
## Manage failed files
You can review the processing status for all incoming and outgoing files on the **Files** page.
You can individually retry or ignore failed files. You can also bulk retry or ignore multiple files at once.
* To bulk retry, click **Retry**. Core automatically retries processing for every file with the Failed status.
* To bulk ignore, click **Ignore**. You may want to ignore executions when they contain an outdated version of a file that you no longer need to retry.
Typically, you would retry a file execution if you have resolved the issue that caused the failure. For example, if a file failed because it was missing a required segment, you could retry the file execution after marking the segment as optional in the guide. You would ignore a file execution if you do not want to reprocess the file. For example, if you inputted the failed file to your system manually, you could ignore the file execution to prevent it from being processed again.
### Bulk processing
Before you initiate a bulk retry or ignore, you can filter the list of files to only show the files you want to take action on. For example, you could filter the list to show only files with a certain fault reason, and then bulk retry or ignore all of those files.
To bulk retry or ignore, click **Retry** or **Ignore**. After a confirmation step, Stedo triggers a retry or ignore for every file with the `Failed` status that matches your selected filters.
## Data retention
Artifacts refer to the transaction and file execution payloads from files Stedi has processed. They contain the actual input/output transaction data in EDI, JSON, or another format. Artifacts do not include the metadata about a transaction or file execution, such as whether it was processed successfully.
By default, Stedi retains your artifact files for 10 years. In some cases, you may want Stedi to remove artifacts to comply with PII/PHI retention policies. You can configure data retention on the [EDI Settings](https://portal.stedi.com/app/core/settings) page.
# Get Execution Input
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-executions-input
***
title: Get Execution Input
sidebarTitle: 'Input'
openapi: core get /executions/{executionId}/input
-------------------------------------------------
This endpoint retrieves a file execution's input document before it passes through any translation or mappings.
The input document can be in either X12 EDI or JSON format, depending on the direction of the file. For example:
* If you send an 834 benefit enrollment to a payer, the input document will be in the JSON format you submitted to Stedi’s API.
* If a payer sends you an 835 ERA, the input document will be in the original X12 EDI format.
There are no size restrictions on documents when fetching from this endpoint.
## Response
This endpoint returns a `302` Temporary redirect to the document download URL. Many HTTP clients will automatically follow this redirect, or have a simple follow redirects configuration to set. For example, the `-L` or `--location` flags in cURL requests will automatically follow the redirect. In this case, the response will contain the full input document.
In the event you cannot, or chose not to automatically follow the redirect, the body of the response contains a JSON object with a single key `documentDownloadUrl` which contains a temporary URL to download the document. This URL is available for 60 minutes.
# Get Execution Metadata
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-executions-metadata
***
title: Get Execution Metadata
sidebarTitle: 'Metadata'
openapi: core get /executions/{executionId}/metadata
----------------------------------------------------
This endpoint retrieves a file execution's metadata document.
There are no size restrictions on documents when fetching from this endpoint.
## Response
This endpoint returns a 302 Temporary redirect to the document download URL. Many HTTP clients will automatically follow this redirect, or have a simple follow redirects configuration to set. For example, using the `-L` or `--location` flag in cURL will automatically follow the redirect. In this case, the response will contain the full metadata document.
In the event you cannot, or chose not to automatically follow the redirect, the body of the response contains a JSON object with a single key `documentDownloadUrl` which contains a temporary URL to download the document. This URL is available for 60 minutes.
## Example
The following is an example of the metadata document for a 277CA claim acknowledgment:
```json Example X12 metadata response
{
"version": "2024-01-01",
"interchanges": [
{
"envelope": {
"senderQualifier": "ZZ",
"senderId": "STEDITEST",
"receiverQualifier": "ZZ",
"receiverId": "111222333444555",
"date": "2025-02-12",
"time": "22:20",
"versionNumberCode": "00501",
"controlNumber": 11,
"acknowledgmentRequestedCode": "0",
"usageIndicatorCode": "T",
"trailer": {
"numberOfIncludedFunctionalGroups": 1,
"controlNumber": 11
},
"segments": {
"isa": "ISA*00* *00* *ZZ*STEDITEST *ZZ*111222333444555 *250212*2220*^*00501*000000011*0*T*:",
"iea": "IEA*1*000000011"
}
},
"acknowledgments": [],
"standard": "x12",
"span": {
"start": 0,
"end": 941
},
"delimiters": {
"segment": "~",
"element": "*",
"composite": ":",
"repetition": "^"
},
"functionalGroups": [
{
"envelope": {
"functionalIdentifierCode": "HN",
"applicationSenderCode": "STEDITEST",
"applicationReceiverCode": "111222333444555",
"date": "2025-02-12",
"time": "22:20:43",
"controlNumber": 11,
"responsibleAgencyCode": "X",
"release": "005010X214",
"trailer": {
"numberOfIncludedTransactionSets": 1,
"controlNumber": 11
},
"segments": {
"gs": "GS*HN*STEDITEST*111222333444555*20250212*222043*11*X*005010X214",
"ge": "GE*1*11"
}
},
"span": {
"start": 106,
"end": 925
},
"transactionSets": [
{
"id": "277",
"controlNumber": "1001",
"implementationConventionReference": "005010X214",
"trailer": {
"numberOfIncludedSegments": 26,
"controlNumber": "1001"
},
"span": {
"start": 167,
"end": 917
},
"trackedIdentifiers": {
"BHT-03": [
"181135085"
],
"TRN-02": [
"20250212170508224",
"12341234",
"0",
"01J99GTR3J1X4C303BCMEX2KSZ"
]
}
}
]
}
]
}
]
}
```
# Get Execution Output
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-executions-output
***
title: Get Execution Output
sidebarTitle: 'Output'
openapi: core get /executions/{executionId}/output
--------------------------------------------------
This endpoint retrieves a file execution's output document, which is the result after Stedi has finished translating and mapping the input document. For example, if you send an 834 benefit enrollment to a payer, the output document will be an X12 EDI 834 benefit enrollment transaction.
There are no size restrictions on documents when fetching from this endpoint.
You can only call this endpoint for outbound files that you send to your trading partner. If you call the API for an inbound file, the endpoint returns a `404` Not Found response.
## Response
This endpoint returns a `302` Temporary redirect to the document download URL. Many HTTP clients will automatically follow this redirect, or have a simple follow redirects configuration to set. For example, the `-L` or `--location` flags in cURL requests will automatically follow the redirect. In this case, the response will contain the full output document.
In the event you cannot, or chose not to automatically follow the redirect, the body of the response contains a JSON object with a single key `documentDownloadUrl` that contains a temporary URL to download the document. This URL is available for 60 minutes.
# Get Execution Transactions
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-executions-transactions
***
title: Get Execution Transactions
sidebarTitle: 'List execution transactions'
openapi: core get /executions/{executionId}/transactions
--------------------------------------------------------
This endpoint retrieves information about all transactions Stedi has processed for a specific file execution. Transactions are sorted by creation date from newest to oldest.
# Get Execution
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-executions
***
title: Get Execution
sidebarTitle: 'Execution'
openapi: core get /executions/{executionId}
-------------------------------------------
# List Executions
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-list-executions
***
title: List Executions
sidebarTitle: 'List executions'
openapi: core get /executions
-----------------------------
This endpoint retrieves information about all file executions that Stedi has processed in your account. It's useful for displaying a list of processed files in a UI. If you want to programmatically fetch and check for new file executions, you should use the [Poll Executions](/api-reference/edi-platform/core/get-pollingexecutions) endpoint instead.
# List Transactions
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-list-transactions
***
title: List Transactions
sidebarTitle: 'List transactions'
openapi: core get /transactions
-------------------------------
This endpoint fetches a list of all the transactions Stedi has processed in your account. It's useful for displaying a list of transactions in a UI. If you want to programmatically fetch and check for new transactions, you should use the [Poll Transactions](/api-reference/edi-platform/core/get-pollingtransactions) endpoint instead.
# Poll Executions
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-pollingexecutions
***
title: Poll Executions
sidebarTitle: 'Poll executions'
openapi: core get /polling/executions
-------------------------------------
This endpoint returns file executions that Stedi processed after the specified `startDateTime`.
Executions are ordered from oldest to newest according to the `processedAt` property. This is exclusive of the `startDateTime`. For example, if the provided startDateTime is `2023-08-10T18:00:00Z`, an execution processed at exactly that time would not be included in the results. There is also a fifteen-second window where newly created executions are excluded, meaning Stedi returns results up to fifteen seconds before the time of your request. This functionality accounts for any network latency or clock drift within the systems to ensure you don't miss any executions.
## Polling with page tokens
We **don't** recommend polling using `startDateTime` only. Due to the exclusive nature of `startDateTime`, you could potentially miss an execution if two executions occur at the *exact* same time and are on the edge of a pagination. Instead, you should use `pageToken`.
After the initial request, you can poll again immediately using `pageToken` to continue iterating through the pages of executions. The endpoint always returns a `nextPageToken`, regardless of whether additional executions match the request criteria. If the `items` array is empty, continue using the provided `nextPageToken` to poll for new executions. New executions will be returned when available.
We recommend storing `pageToken` values as part of your polling process. They don't expire, allowing you to start from that point in the execution stream again if you need to catch a system up to date or recover from a failure.
Note that `pageToken` values are unique per request, opaque, and shouldn't be parsed or modified in any way. They are not guaranteed to be in any particular format, and may change in the future.
# Poll transactions
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-pollingtransactions
***
title: Poll transactions
openapi: core get /polling/transactions
---------------------------------------
This endpoint returns details about transactions that Stedi processed after the specified `startDateTime`.
Transactions are ordered from oldest to newest according to the `processedAt` property. This is *exclusive* of the `startDateTime`. For example, if the provided `startDateTime` is `2023-08-10T18:00:00Z`, a transaction processed at exactly that time would not be included in the results. There is also a fifteen-second window where newly created transactions are excluded, meaning Stedi returns results up to fifteen seconds before the time of your request. This functionality accounts for any network latency or clock drift within the systems to ensure you don't miss any transactions.
## Polling with page tokens
We **don't** recommend polling using `startDateTime` only. Due to the exclusive nature of `startDateTime`, you could potentially miss a transaction if two transactions occur at the *exact* same time and are on the edge of a pagination. Instead, you should use `pageToken`.
After the initial request, you can poll again immediately using `pageToken` to continue iterating through the pages of transactions. The endpoint always returns a `nextPageToken`, regardless of whether additional transactions match the request criteria. If the `items` array is empty, continue using the provided `nextPageToken` to poll for new transactions. New transactions will be returned when available.
We recommend storing `pageToken` values as part of your polling process. They don't expire, allowing you to start from that point in the transaction stream again if you need to catch a system up to date or recover from a failure.
Note that `pageToken` values are unique per request, opaque, and shouldn't be parsed or modified in any way. They are not guaranteed to be in any particular format, and may change in the future.
# Get Fragment
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-transaction-fragment-detail
***
title: Get Fragment
sidebarTitle: "Fragment"
openapi: core get /transactions/{transactionId}/fragments/{fragmentIndex}
-------------------------------------------------------------------------
This endpoint retrieves metadata about a specific fragment within a transaction. To retrieve the fragment itself, use the [Get Fragment Output](/api-reference/edi-platform/core/get-transaction-fragment-output) endpoint.
[Fragments](/edi-platform/fragments) allow you to split large transactions into smaller chunks for easier processing. You can enable fragments for one repeated EDI segment in each transaction set and then split the transaction into chunks based on that segment.
# Get Fragment Output
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-transaction-fragment-output
***
title: Get Fragment Output
sidebarTitle: 'Output'
openapi: core get /transactions/{transactionId}/fragments/{fragmentIndex}/output
--------------------------------------------------------------------------------
There are no size restrictions on documents when fetching from this endpoint. However, fragments are generally smaller and more consumable than entire transactions.
## Response
This endpoint returns a `302` Temporary redirect to the document download URL. Many HTTP clients will automatically follow this redirect, or have a simple follow redirects configuration to set. For example, using the `-L` or `--location` flag in cURL will automatically follow the redirect. In this case, the response will contain the fragment data.
In the event you cannot, or chose not to automatically follow the redirect, the body of the response contains a JSON object with a single key `documentDownloadUrl` which contains a temporary URL to download the document. This URL is available for 60 minutes.
## Example
The following example shows a fragment from an 846 Inventory Inquiry/Advice transaction. It contains two iterations of the `item_identification_LIN` loop.
```json
{
"item_identification_LIN_loop": [
{
"item_identification_LIN": {
"assigned_identification_01": "1",
"product_service_id_qualifier_02": "VC",
"product_service_id_03": "AAD15-1000"
},
"quantity_information_QTY_loop": [
{
"quantity_information_QTY": {
"quantity_qualifier_01": "17",
"quantity_02": 0,
"composite_unit_of_measure_03": {
"unit_or_basis_for_measurement_code_01": "EA"
}
}
},
{
"quantity_information_QTY": {
"quantity_qualifier_01": "ZZ",
"quantity_02": 179.45,
"composite_unit_of_measure_03": {
"unit_or_basis_for_measurement_code_01": "DO"
}
}
}
]
},
{
"item_identification_LIN": {
"assigned_identification_01": "2",
"product_service_id_qualifier_02": "VC",
"product_service_id_03": "AAD15-2"
},
"quantity_information_QTY_loop": [
{
"quantity_information_QTY": {
"quantity_qualifier_01": "17",
"quantity_02": 0,
"composite_unit_of_measure_03": {
"unit_or_basis_for_measurement_code_01": "EA"
}
}
},
{
"quantity_information_QTY": {
"quantity_qualifier_01": "ZZ",
"quantity_02": 179.45,
"composite_unit_of_measure_03": {
"unit_or_basis_for_measurement_code_01": "DO"
}
}
}
]
}
]
}
```
# Get Transaction Input
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-transactions-input
***
title: Get Transaction Input
sidebarTitle: 'Input'
openapi: core get /transactions/{transactionId}/input
-----------------------------------------------------
This endpoint retrieves a transaction's input document before it passes through any translation or mappings.
The input document can be in either X12 EDI or JSON format, depending on the direction of the transaction. For example:
* If you send an 834 benefit enrollment to a payer, the input document will be in the JSON format you submitted to Stedi's API.
* If a payer sends you an 835 ERA, the input document will be in the original X12 EDI format.
There are no size restrictions on documents when fetching from this endpoint.
## Response
This endpoint returns a `302` Temporary redirect to the document download URL. Many HTTP clients will automatically follow this redirect, or have a simple follow redirects configuration to set. For example, using the `-L` or `--location` flag in cURL will automatically follow the redirect. In this case, the response will contain the full transaction input document.
In the event you cannot, or chose not to automatically follow the redirect, the body of the response contains a JSON object with a single key `documentDownloadUrl` which contains a temporary URL to download the document. This URL is available for 60 minutes.
# Get Transaction Output
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-transactions-output
***
title: Get Transaction Output
sidebarTitle: 'Output'
openapi: core get /transactions/{transactionId}/output
------------------------------------------------------
This endpoint retrieves a transaction's output document, which is the result after Stedi has finished translating and mapping the input document.
The output document can be in either X12 EDI or JSON format, depending on the direction of the transaction. For example:
* If you send an 834 benefit enrollment to a payer, the output document will be an X12 EDI 834 benefit enrollment transaction.
* If a payer sends you an 835 ERA, the output document will be a JSON representation of the 835 ERA.
There are no size restrictions on documents when fetching from this endpoint.
## Response
This endpoint returns a `302` Temporary redirect to the document download URL. Many HTTP clients will automatically follow this redirect, or have a simple follow redirects configuration to set. For example, using the `-L` or `--location` flag in cURL will automatically follow the redirect. In this case, the response body will contain the full transaction output document.
In the event you cannot, or chose not to automatically follow the redirect, the body of the response contains a JSON object with a single key `documentDownloadUrl` which contains a temporary URL to download the document. This URL is available for 60 minutes.
# Get Transaction
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/get-transactions
***
title: Get Transaction
sidebarTitle: 'Transaction'
openapi: core get /transactions/{transactionId}
-----------------------------------------------
This endpoint retrieves information about the transaction with the specified `transactionId`.
# Stage fragment
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/post-fragments
***
title: "Stage fragment"
openapi: core post /fragments/{fragmentGroupId}
-----------------------------------------------
You can optionally specify a [mapping](/edi-platform/mappings) to transform the fragment to Stedi's Guide JSON format. If you don't specify a mapping, the fragment must match the [Guide JSON](/edi-platform/operate/transform-json/guide-json) format for the specified guide.
[Fragments](/edi-platform/fragments) allow you to split large transactions into smaller chunks for easier processing. You can enable fragments for one repeated EDI segment in each transaction set and then split the transaction into chunks based on that segment. For example, if you enable fragments on the `LIN` loop in an 846 Inventory Inquiry/Advice, you can stage fragments containing batches of `LIN` loops. Later, when you call the Create Outbound Transaction endpoint, Stedi stitches the fragments together into a single transaction and delivers it to your trading partner.
# Stage transactions
Source: https://www.stedi.com/docs/api-reference/edi-platform/core/stage-transactions
***
title: 'Stage transactions'
openapi: core post /partnerships/{partnershipId}/transaction-groups/{transactionGroupId}/transactions/{transactionSettingId}
----------------------------------------------------------------------------------------------------------------------------
Stedi stores the transaction in the transaction group specified by the `transactionGroupId`. If a group with that ID does not exist, Stedi creates one.
When you're ready to send all of the transactions in the group, call the [Deliver Transaction Group](/api-reference/edi-platform/post-transaction-group) endpoint with the `transactionGroupId` to generate and deliver a fully-formed EDI file to your trading partner.
## Transaction data
You provide transaction data in [Guide JSON](/edi-platform/operate/transform-json/guide-json) format. The transaction data must be \< 5MB.
All of the transactions you stage in a transaction group must use the same transaction settings. If you attempt to stage a transaction with different settings, Stedi returns an error.
# Configure destinations
Source: https://www.stedi.com/docs/edi-platform/configure/destinations/configure-destinations
***
title: Configure destinations
sidebarTitle: Configure destinations
------------------------------------
Destinations is a legacy feature. It is not deprecated, but it has been
superseded by [Webhooks](/edi-platform/configure/webhooks). Please [contact
support](https://www.stedi.com/contact) with questions.
To configure a destination webhook, you must first create an [auth](#auth), then one or more [destinations](#destination) for the auth, and then one or more [event bindings](#event-bindings) that trigger each destination.
You may want to configure webhooks to:
* Send processed transaction data to an external system. You can optionally attach a Stedi mapping to transform the payload before sending it to the destination. We recommend only using a mapping with a destination when you know your mapping output will be under 1MB in size. Otherwise, you can use the [Map Transaction Output](/api-reference/edi-platform/get-map-transaction-output) endpoint to retrieve mapped data asynchronously.
* Send Stedi events to systems like Slack and PagerDuty or to implement more advanced functionality.
## Auth
An auth defines how to authenticate with a specific API. You can use a single auth configuration across multiple destinations. Stedi supports the following types of auth configurations.
| Type | Description |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API Keys | The API keys as headers in the request. The most common version is ‘bearer tokens’. |
| Basic Auth | [HTTP Basic Auth](https://developer.mozilla.org/en-US/Web/HTTP/Authentication), where you provide a username and password. |
| OAuth 2.0 | [OAuth 2.0 Auth](https://oauth.net/2/), where you can set the Authorization endpoint and parameters, the HTTP method, a client ID, and a client secret. |
### Unauthenticated endpoints
There isn't a 'no-auth' option with Destinations, but you can achieve this by configuring the API Keys auth to use arbitrary values for `Header name` and `Value` (e.g. `Header name: x-stedi-noauth` and `Value: dummy`). Since the receiving API isn't authenticating the call, it will ignore these values and accept the request.
### Create auth
To create a new auth:
1. Go to the [Destinations](https://portal.stedi.com/app/events/destinations) page.
2. Click **Add new auth**.
3. Enter a name for the auth.
4. Choose the appropriate **Authentication type**.
5. Enter the details for the auth.
6. Click **Done**.
## Destination
The destination defines which URL endpoint should be called when the destination is invoked, and which HTTP method to use (`POST`, `PUT`, `GET`, `PATCH`, `DELETE`).
Destinations are scoped to a single auth. However, you might have multiple destinations for a single system integration, each with a different endpoint. For example, one endpoint for creating Sales Orders and another for Item Fulfillments.
### Create destination
To create a new destination:
1. Go to the [Destinations](https://portal.stedi.com/app/events/destinations) page.
2. Under the desired auth, click **Add destination**.
3. Enter a name.
4. Choose a **Method** and enter an **Endpoint**.
5. (Optional) Enter a **Max executions per second**. Use this to avoid overloading the target service.
## Event bindings
Event bindings allow you to specify which events trigger the destination webhook. You can create multiple event bindings for a single destination. For example, you may want to create an event binding for each type of transaction you want to send to your API.
### Create event binding
To create a new event binding:
1. Go to the [Destinations](https://portal.stedi.com/app/events/destinations) page.
2. Click the desired destination.
3. Click the **Edit** tab.
4. Click **Add event binding**.
5. Choose an **Event detail-type** and complete the remaining fields.
6. (Optional) Select a mapping to transform the payload before sending it to the destination. This is only available for `transaction.processed.v2` and `fragment.processed.v2` events.
7. Click **Create binding**.
## Send transaction data
You can create a `transaction.processed.v2` event binding to send processed transaction data to external APIs. If the transaction set uses [fragments](/edi-platform/fragments) to split the payload into smaller chunks, you can also configure an event binding for `fragment.processed.v2` events.
You can optionally add a Stedi mapping to both types of event bindings to transform the payload shape before sending it to the destination.
### Event types
Stedi emits a `transaction.processed.v2` event each time it processes a transaction. An EDI file can contain multiple transactions, so a single EDI file can produce multiple events that each invoke the configured destination webhook. When you use a `transaction.processed.v2` event to trigger a destination, Stedi includes the [Guide JSON](/edi-platform/operate/transform-json/guide-json) transaction in the payload along with the event data.
The transaction itself is only included as part of the event if the whole response (payload + event) is \< 1MB. Otherwise, the event will contain a section that specifies the transaction was too big to be included and you can retrieve the actual transaction by making a request to the `transaction` artifact.
When [fragments](/edi-platform/fragments) are enabled, the `transaction.processed.v2` payload includes an empty array in place of the fragmented segment. Stedi then emits one `fragment.processed.v2` event for each fragment within the processed transaction. The event contains a link you can use to retrieve the fragment data as well as information about the original transaction, such as the `ISA` and `GS` headers.
Refer to [Events](/edi-platform/operate/event-types) for complete details and examples.
### Configure event bindings
Choose `transaction.processed.v2` or `fragment.processed.v2` as the **Event detail-type** and complete the following fields:
1. (Optional) Choose a **Transaction set ID**. This is useful if you want to send different transaction sets to different endpoints. For example, you could send 850 Purchase Orders to one endpoint and 860 Purchase Order Change Requests to another.
2. (Optional) Choose a **Partnership ID**. This is useful if you want to send transactions from different partners to different endpoints. For example, you could send transactions from Walmart to one endpoint and transactions from Target to another. This is less common.
3. (Optional) Select a **Guide**. This is useful if you want to send transactions parsed using different guides to different endpoints. For example, you may receive `005010` 850 Purchase Orders from two different retailers, and those retailers have different guides. Since the transaction payloads will differ, you may want to send them to different API endpoints within your system.
4. (Optional) You can configure the following **Advanced** settings:
* **Connection:** This is useful when you are using multiple connections for a single partnership. For example, you may have set up one connection type for test data and a separate connection for production data.
* **Mode:** Specify the type of data Stedi is sending to the destination. You can choose from **Test** or **Production**.
5. (Optional) Select a **Guide** + **Mapping**. This is useful if you want to send transactions parsed using different guides to the same endpoint. For example, you may receive `005010` 850 Purchase Orders from two different retailers, and those retailers have different guides. Since the transaction payloads will differ, you can [choose a mapping](#transform-data-with-mappings) to convert the 850s to your API shape.
{" "}
If you plan to [add a mapping](#transform-data-with-mappings) to this event
binding, you must select a guide. When you add a mapping, you are only able
to select a mapping that uses the same guide as a `source`.
## Transform data with mappings
Stedi integrations use [Guide JSON](/edi-platform/operate/transform-json/guide-json), a JSON format that closely reflects the structure of an EDI transaction. You may need to reshape transaction data from Guide JSON format into the shape required for the target API. For example, you may need to rename fields, add or remove fields, or change the data type of a field.
You can use the [Mappings module](/edi-platform/mappings) to transform your payload into the required shape before sending it to a destination.
### Size limits
Two size limits must be met for Stedi to both deliver the event and include the transaction data in the event payload.
1. The enriched event must be less than 4 MB when Stedi passes it to the mapping.
2. The mapping output must be under 1MB.

If either of these size limits fails, Stedi considers the event delivery a failure and adds the event to the destination's error queue. Instead, you can:
* Use [fragments](/edi-platform/fragments) to split the transaction payload into smaller chunks before sending it to a destination.
* Use the [Map Transaction Output](/api-reference/edi-platform/get-map-transaction-output) endpoint to retrieve processed, mapped transaction data from Stedi.
### Add a Stedi mapping
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
To add a mapping:
1. Use the [mappings editor](https://portal.stedi.com/app/mappings) to create a transformation for the event. You must choose the event when creating the source schema. Refer to the [mappings documentation](/edi-platform/mappings/manage-mappings/ui-guide) for instructions.
2. Select the mapping in the **Mapping** menu when creating your event binding. You will only be able to select mappings that use the same guide you selected in the event binding.
Stedi will apply the mapping to the event data before sending it to the destination.
# Destinations error handling and limitations
Source: https://www.stedi.com/docs/edi-platform/configure/destinations/error-handling-destinations
***
title: Destinations error handling and limitations
sidebarTitle: Error handling and limitations
--------------------------------------------
{" "}
Destinations is a legacy feature. It is not deprecated, but it has been
superseded by [Webhooks](/edi-platform/configure/webhooks). Please [contact
support](https://www.stedi.com/contact) with questions.
[Destination webhooks](/edi-platform/configure/destinations/configure-destinations) allow you to send data from Stedi to third-party services without writing any custom code.
## Limitations
Destinations has certain limitations. If your system's API has different requirements, you can set the destination target to be:
* A function, such as AWS Lambda, Google Cloud Functions, or Azure Functions, which can then call the third-party API
* An iPaaS platform, such as Zapier or Workato, which can then call the third-party API.
## HTTP response codes
Stedi considers a `2xx` response a success, and marks any other response as a failure.
Stedi retries events associated with status codes other than `2xx` for up to 5 hours.
In the event of an error response (after the retry period), Stedi adds the event to the [error queue](#error-queue) for the destination.
To prevent throttling, you can set a **Max executions per second** when [configuring the destination](/edi-platform/configure/destinations/configure-destinations#create-destination).
## Response time
The target endpoint must respond within 5 seconds, or the event will be counted as a failed delivery.
## Retries
When a destination delivery fails, Stedi will retry up to 5 times every 90 seconds. After the fifth retry, Stedi moves the event to the error queue.
## Error queue
Each destination includes an error queue. Each item in the queue consists of the original event that was attempted to be delivered. This ensures if the target service has some downtime, or anything else goes wrong, the missed events can be retried later. The error queue retains items for 14 days.
Viewing the HTTP response from the third-party service is not currently supported.
The order of the error queue is not guaranteed. The downstream service must be designed to be idempotent to handle at-least-once delivery of events, and must accept events out of order.
## Logs
To view logs, click the Destination to go to its detail page, and then navigate to the **Logs** tab.
## Deauthorized connections
If a destination sends a message to an endpoint that returns a 401 (Unauthorized) response, or the OAuth endpoint returns an error, the destination will be 'deauthorized'. In this state, the destination won't be able to deliver messages.
If there is an issue with your authentication information (such as the password, API key, or OAuth settings), edit the destination to fix it.
If the authentication information is correct, and there was a different reason for the endpoint returning a 401, you can try again by adding a temporary header. Edit the destination, and under the advanced toggle, add any header and value. For example, `x-stedi-reauthorize` with today's date as a value. When you save, the destination will attempt to deliver again. This header can be removed later. Editing the value of a header will also restart deliveries.
You will likely have a queue of messages to deliver, so after making this change they will start automatically being retried. If the endpoint is still returning an invalid response, the destination will return to `Deauthorized`
# Destinations overview
Source: https://www.stedi.com/docs/edi-platform/configure/destinations
***
title: Destinations overview
sidebarTitle: Overview
----------------------
{" "}
Destinations is a legacy feature. It is not deprecated, but it has been
superseded by [Webhooks](/edi-platform/configure/webhooks). Please [contact
support](https://www.stedi.com/contact) with questions.
Each time you receive an EDI file from a trading partner, you will want to send the included transactions to your downstream system for processing. You can do this by configuring a Destination webhook. Destination webhooks allow you to send data from Stedi to third-party services without writing any custom code.
The most common use case is sending processed transaction data to your internal systems and business applications. You can also configure webhooks for other [Stedi events](/edi-platform/operate/event-types), like when a processing error occurs. This can be used to trigger alerts in systems like Slack, PagerDuty, or Zendesk for further review.
Stedi can send webhooks to:
* Custom applications using Basic, OAuth, or API Key authorization
* Cloud functions, including AWS Lambda, Google Cloud Functions, and Azure Functions
* iPaaS platforms, such as Zapier, Workato, or Tray.io
* ERPs like NetSuite, SAP, or Oracle.
# Acknowledgments
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/functional-acknowledgments
***
title: Acknowledgments
sidebarTitle: Acknowledgments
description: ""
---------------
Your trading partner may send you TA1s in response to outbound EDI files.
You may also need to send your trading partner a TA1 and/or a functional acknowledgment (997 or 999) in response to each inbound EDI file. These acknowledgments confirm that you received the transaction and help your trading partner know everything is working as expected.
Stedi can automatically generate acknowledgments for each inbound transaction and deliver them to your trading partner.
## TA1s
[TA1 Interchange Acknowledgments](https://www.stedi.com/edi/x12-008040/segment/TA1) indicate receipt of an interchange and identify any errors in the interchange's envelope (`ISA` and `IEA`) information.
### Inbound
You don't need to create a transaction setting to receive TA1s from your trading partners. Stedi automatically processes inbound TA1s and displays the data in the [Files](https://portal.stedi.com/app/core/file-executions) and [Transactions](https://portal.stedi.com/app/core/transactions) pages for inspection.
### Outbound
Stedi can automatically send both positive and negative TA1s in response to inbound transactions from your trading partner. If you specify a connection for automatic acknowledgments, Stedi sends the TA1 to that connection. Otherwise, Stedi sends the TA1 through the connection that received the inbound file.
You can review the TA1s Stedi sends to trading partners on the [Files](https://portal.stedi.com/app/core/file-executions) page in the Stedi portal.
#### Positive TA1s
Positive TA1s contain code `A` in `TA104`, indicating that the interchange was accepted without errors. Stedi will then process the transaction and create a record in the Stedi portal.
Note that a positive TA1 only indicates that Stedi received the interchange and that the interchange envelope does not contain any of the errors that trigger a [negative TA1](#negative-ta1s). The transaction data can still fail Stedi’s validation and processing. For example, your partner could receive a positive TA1 and then a 999 rejection (if configured) for the transaction itself due to non-compliant EDI.
#### Negative TA1s
Stedi only generates negative TA1s for specific errors. If the interchange envelope contains a different error than the ones listed, Stedi still sends a positive TA1 (if configured) so your trading partner can confirm you received the transaction.
Your trading partner may receive the following types of negative TA1s:
* **Accepted with errors:** TA1s with [code `E` in `TA104`](https://www.stedi.com/edi/x12/segment/TA1#TA1-04) indicate that the interchange was accepted with errors. In these cases, Stedi still proceeds with processing the transaction and creates a record in the Stedi portal. Stedi generates TA1s with code `E` for the following `TA105` error types:
* `014`: Invalid Interchange Date Value
* `015`: Invalid Interchange Time Value
* **Rejected because of errors:** TA1s with [code `R` in `TA104`](https://www.stedi.com/edi/x12/segment/TA1#TA1-04) indicate that the interchange was rejected due to one or more errors. Stedi doesn't process the interchange and doesn't create a record in the Stedi portal. Stedi generates TA1s with code `R` for the following `TA105` error types:
* `001`: The Interchange Control Number in the Header and Trailer Do Not Match. The Value From the Header is Used in the Acknowledgment
* `021`: Invalid Number of Included Groups Value | For example, the interchange envelope indicates that there are five functional groups, but only four are present in the interchange.
* `027`: Invalid Component Element Separator | The data cannot use letters, numbers, whitespace, or the underscore character as a separator between EDI elements.
#### Enable automatic TA1s
To enable autogenerating outbound TA1s for trading partners:
1. Go to the partnership.
2. Click the pencil next to **Acknowledgments**.
3. Select an option under **Interchange Acknowledgments (TA1)**:
* **Never:** This is the default setting.
* **When requested**: Stedi sends a TA1 according to the [code provided in `ISA14`](https://www.stedi.com/edi/x12/segment/ISA#ISA-14). There are four possible codes:
* `0`: Never send a TA1
* `1`: Always send a TA1 (positive or negative)
* `2`: Only send TA1s with code `R` (rejected)
* `3`: Only send TA1s with code `R` or code `E` (accepted with errors)
* **Always:** Stedi sends a TA1 for every successful inbound transaction received over a connection within this partnership.
4. Select an existing **Connection** within the partnership where Stedi will deliver generated TA1s.
* (SFTP/FTPS only) Specify an optional **Subdirectory**. Stedi will deliver generated acknowledgments to this subdirectory. We don't recommend specifying a subdirectory unless your trading partner has instructed you to do so.
5. (Optional) Enter a JSONata expression to set a custom filename for generated acknowledgments. Available JSONata expressions are `& (Concatenation)` and `$millis`. If you do not set a filename, Stedi uses the **File Execution ID**.
6. Click **Save**.
## 997s and 999s
[997 Functional Acknowledgments](https://www.stedi.com/edi/x12/transaction-set/997) and [999 Implementation Acknowledgments](https://www.stedi.com/edi/x12/transaction-set/999) are functional acknowledgments that confirm receipt of a transaction and indicate whether it was accepted or rejected. The acknowledgment also provides information about errors in the transaction, if present. While they serve the same basic purpose, 999s are more detailed than 997s and are currently only used in healthcare.
### Inbound
You must create [inbound transaction settings](/edi-platform/configure/trading-partners/transaction-settings) if your trading partner plans to send you 997 or 999 functional acknowledgments.
### Outbound
When sending outbound functional acknowledgments, you should never return both a 997 and a 999 for a given file. 999s are commonly returned for the following healthcare transaction sets:
* [270 Health Care Eligibility, Coverage or Benefit Inquiry](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-inquiry-x279a1/01GRYB6GTDJ4MEP5Z16CGMQWT6)
* [271 Health Care Eligibility Benefit Response](https://portal.stedi.com/app/guides/view/hipaa/health-care-eligibility-benefit-response-x279a1/01GS66YHZPB37ABF34DBPSR213)
* [276 Health Care Claim Status Request](https://portal.stedi.com/app/guides/view/hipaa/claim-status-request-x212/01GRYB6A4XEJQ61Y2K2KT606E5),
* [277 Health Care Information Status Notification](https://www.stedi.com/edi/x12/transaction-set/277)
* [278 Health Care Services Review Information - Response](https://portal.stedi.com/app/guides/view/hipaa/health-care-services-review-information-response-x217/01GRYB6C27KFB6H1M8MVYMQDKK)
* [820 Payroll Deducted and Other Group Premium Payment for Insurance Products Examples](https://portal.stedi.com/app/guides/view/hipaa/payroll-deducted-and-other-group-premium-payment-for-insurance-products-examples-x218/01GRYB6CPB1S1257NJJP6K497B)
* [834 Benefit Enrollment and Maintenance](https://portal.stedi.com/app/guides/view/hipaa/benefit-enrollment-and-maintenance-x220a1/01GRYB6D6RAWSG8ATBD6GXM13C)
* [835 Health Care Claim Payment/Advice](https://portal.stedi.com/app/guides/view/hipaa/health-care-claim-paymentadvice-x221a1/01GRYB6DS30MGXWBPFZCM3695E)
* [837 Health Care Claim](https://www.stedi.com/edi/x12/transaction-set/837)
#### Positive
When configured, Stedi autogenerates a 997 or 999 acknowledgment for every successful inbound EDI transaction received over a partnership connection, even if the transaction set has not been explicitly configured as an inbound transaction setting. Acknowledgments are generated at the functional group level and contain complete `ISA` and `GS` envelopes, including control numbers.
If only positive acknowledgments are enabled, Stedi does not send an acknowledgment until the file is processed successfully. Per the X12 EDI specification, Stedi doesn't generate acknowledgments in response to
inbound acknowledgments.
#### Negative
For 999s only, you can also configure Stedi to generate negative acknowledgments. A negative acknowledgment indicates that the transaction set was rejected and provides information about the errors.
While negative 997s aren't supported, Stedi generates a [`file.failed.v2` event](/edi-platform/operate/event-types#file-failed) when a file fails validation or processing. You can use this event to trigger a 997 rejection from your system.
### Enable automatic 997s or 999s
Before you begin, you must define at least one [connection](/edi-platform/configure/trading-partners/connections) for this partnership.
To enable automatic 997 or 999 generation:
1. Go to the partnership.
2. Click the pencil next to **Acknowledgments**.
3. Select **997s** or **999s**.
4. Enable acknowledgments. For 997s you can send positive acknowledgments only. For 999s you can send positive and negative acknowledgments.
5. Select an existing **Connection** within the partnership. Stedi delivers generated acknowledgments using this connection.
* (SFTP/FTPS only) Specify an optional **Subdirectory**. Stedi will deliver generated acknowledgments to this subdirectory. We don't recommend specifying a subdirectory unless your trading partner has instructed you to do so.
6. (Optional) Enter a JSONata expression to set a custom filename for generated acknowledgments. Available JSONata expressions are `& (Concatenation)` and `$millis`. If you do not set a filename, Stedi uses the **File Execution ID**.
7. Click **Save**.
# Partnerships
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/profiles-and-partnerships
***
title: Partnerships
sidebarTitle: Partnerships
description: ''
---------------
The first step to add a trading partner is creating a partnership.
## What is a partnership?
Partnerships describe all aspects of the EDI relationship between two profiles in your Stedi account, such as which transaction sets they will exchange and other important information for processing EDI files.
### Types of profiles
Profiles contain the basic information required to construct a valid EDI file. Generally, each profile represents a unique business entity. You can create two types of profiles on Stedi:
* **Local:** Profiles for your company (or a company you represent)
* **Partner:** Profiles for the companies you do business with.
Typically, you create a single local profile for your company and a single partner profile for each of your trading partners. If you're using Stedi to represent multiple companies, then you should create multiple local profiles – one for each of the companies you represent.
In addition to containing important information for processing EDI, profiles also determine the direction of EDI files:
* EDI files are labeled as **inbound** when the **Local** profile is the **receiver**.
* EDI files are labeled as **outbound** when the **Local** profile is the **sender**.
## Create partnerships
To create a partnership manually:
1. Go to the [**Trading partners**](https://portal.stedi.com/app/core/partnerships) page.
2. Click **Create partnership**.
3. Enter the information for a [local profile](#create-local-profiles) and a [partner profile](#create-partner-profiles), or select existing profiles from the menus.
### Create local profile
For most use cases, you will only need to set up a single local profile for your company. You can create a new local profile as part of the [create a partnership](#create-partnerships) flow, or from the [Trading partners](https://portal.stedi.com/app/core/partnerships) page.
You must enter the following information for each local profile:
* **ID Qualifier** and **Interchange ID**: These values are used to populate the [`ISA` header](https://www.stedi.com/edi/x12/segment/ISA) of an EDI file. Your Interchange Qualifier and ID are used by your partner to route EDI files in a similar way to email addresses in an email system. Your trading partner will ask you to provide these values so that they can set you up in their EDI system.
* In most industries, you can choose these values yourself, since there is no central authority that registers and validates Interchange IDs. A safe choice for the ID Qualifier is `ZZ`, which is a catch-all code that means "Mutually Defined". For the Interchange ID, you can use your company's name (e.g. `STEDI`) or an identifier that you use internally. It's customary for these values to be all uppercase with no spaces or special characters.
* If you are unsure of what to use, or if your trading partner has specific requirements, [reach out to us](https://www.stedi.com/contact) and we can help you choose the right values.
* **Identifier**: This is never visible to your trading partner and is used for unique identification within your Stedi account only. You can change this value to anything you wish. You cannot edit the name after the profile has been created.
* **Application ID**: This is used to populate the [GS header](https://www.stedi.com/edi/x12/segment/GS) of an EDI file. Stedi will automatically suggest the same value that you inputted for your Interchange ID, which is the right choice for most use cases. This can be changed at any time, and you can add multiple application IDs if needed, so don't worry about getting it right up front. If the need for multiple application IDs arises in the future, you can add them as-needed. For advanced use cases, you can also override the Application ID on the partnership itself.
### Create partner profile
You need to create a partner profile for each of your trading partners. You can create a new partner profile as part of the [create a partnership](#create-partnerships) flow, or from the [Trading partners](https://portal.stedi.com/app/core/partnerships) page.
You must enter the following information for each partner profile:
* **ID Qualifier** and **Interchange ID**: Your partner will provide you with this information as part of the onboarding process. If they haven't already, you should request this from them. If you get stuck or aren't sure what to ask, [reach out to us](https://www.stedi.com/contact) and we can help ensure the profile is set up correctly.
* **Identifier**: This is never visible to your trading partner and is used for unique identification within your Stedi account only. You cannot edit the name after the profile has been created.
* **Application ID**: This value is used to populate the [GS header](https://www.stedi.com/edi/x12/segment/GS) of an EDI file. Stedi will automatically suggest the same value that you inputted for your partner's Interchange ID, which is the right choice for most use cases. Some trading partners use the GS ID to specify a specific department within their business. If your trading partner has asked you to use a specific GS ID (or multiple IDs), you can add them here. This can be changed at any time.
### Finish partnership
Once you have created the local and partner profiles, finalize the partnership:
1. Review the autogenerated **Partnership identifier**. The Partnership identifier is never visible to your trading partner and is only used for unique identification with your Stedi account. You can change it to any value that is the most helpful to you. You cannot edit the name after the profile has been created.
2. Click **Create Partnership**. You will be brought to the partnership details page where you can define additional settings.
## (Advanced) Auto-configure from sample EDI files
If you have EDI files from your trading partner, you can use the auto-configure option to create profiles and partnerships based on those sample files. This is an advanced option that is best suited for migrations.
Stedi extracts information from the file to generate two profiles - one for you and one for your partner – as well as a new partnership between them.
To automatically generate profiles and partnerships from EDI files:
1. Go to the [**Trading partners**](https://portal.stedi.com/app/core/partnerships) page and click **Create partnership**.
2. Click **Advanced** and then the link to **auto-configure partnerships**.
3. Upload an EDI file.
4. Review the profiles to ensure the pre-populated fields are correct. Refer to [create local profiles](#create-local-profiles) and a [create partner profiles](#create-partner-profiles) for field descriptions.
> **Important:** Set your company as the **Local** profile and your trading partner as a **Partner** profile.
5. By default, a partnership will also be created when you click **Create**. To disable the creation of a partnership, toggle the **Create partnership** option to OFF.
6. Click **Create**. Two profiles and the new partnership are created.
You can view the new profiles and partnership on the [**Trading partners**](https://portal.stedi.com/app/core/partnerships) page.
## Next steps
After you create profiles and partnerships, you can configure the details of each partnership to start processing EDI files.
### Configure connections
Within each partnership, you can create one or more SFTP, FTP, FTPS, or AS2 connections in order to exchange files with your trading partner. Visit [connections](/edi-platform/configure/trading-partners/connections) for details.
### Configure transaction settings
Within each partnership, you can define the EDI transaction sets you plan to exchange with trading partners. Visit [transaction settings](/edi-platform/configure/trading-partners/transaction-settings) for details.
### Configure acknowledgments
Stedi can automatically generate a 997 Functional Acknowledgement or a 999 Implementation Acknowledgment for each inbound transaction within a partnership. Visit [Functional acknowledgments](/edi-platform/configure/trading-partners/functional-acknowledgments) for details.
# Transaction settings
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/transaction-settings
***
title: Transaction settings
sidebarTitle: Transaction settings
----------------------------------
Within each [partnership](/edi-platform/configure/trading-partners/profiles-and-partnerships), you can specify the EDI transaction sets that you plan to exchange with that trading partner.
For example, you may want to receive inbound 837P professional claims from a provider and send outbound 835 Electronic Remittance Advice (ERA) transactions to them. This would involve creating an inbound transaction setting for professional claims and an outbound transaction setting for ERAs.
## Create transaction settings
To create a transaction setting, navigate to the partnership and click either:
* **Create inbound transaction setting** to configure a transaction set you plan to receive from your trading partners
* **Create outbound transaction setting** to configure a transaction set you plan to send to your trading partner.
### Choose a transaction set
When you configure a transaction setting, you must select a machine-readable EDI specification ([Stedi guide](/edi-platform/guides)) for the transaction set.
Guides allow Stedi to validate and parse (inbound) or validate and generate (outbound) EDI data according to your and your trading partner's specific requirements.
* **Import from network (recommended):** Search for your trading partner and click **Select** to import a local copy of the guide into your account.
* **My account:** Select an existing guide from your account.
* **Base guide:** Stedi validates the transaction against the generic X12 specification. This option is useful for testing inbound flows when your partner hasn't yet provided a guide. We do not recommend using it for outbound flows except in rare, advanced use cases.
* Select the X12 **Release**. The release is present in the `GS` segment of every EDI file, and also should be specified in your partner’s documentation.
* Select the **Transaction set**. The transaction set is the EDI transaction you are receiving from your partner.
### (Inbound) Configure fragments
If the guide you choose is set up to use [fragments](/edi-platform/fragments), you can enable fragments for the transaction setting. Fragments allow you to split large transactions from Stedi into smaller chunks for downstream ingestion.
### (Outbound) Application IDs
Stedi automatically suggests the default **Application IDs** that were assigned to the local and partner profiles. You can override these values if needed. For example, some trading partners may assign a specific `GS` ID to you during the onboarding process. Since this `GS` ID is used only for this partnership, you would not want to put it in your local profile.
### (Outbound) Connection
Specify the **Connection** to deliver generated EDI files. If no connection is specified, you can't generate outbound EDI files for this transaction.
For **SFTP/FTPS**, You can optionally add a subdirectory that Stedi uses for this transaction set only. For example, your trading partner may require that you place all claims in an `/837` subdirectory. We don't recommend specifying a subdirectory unless your trading partner has instructed you to do so.
### (Outbound) Custom filename expression
By default, Stedi autogenerates a unique name for outbound files using a UUID. To set a custom filename, open **Advanced settings** and enter a JSONata expression into the **Filename expression** field.
You can use `&` (Concatenation), `$random`, or `$millis` in the expression to generate a unique name based on a random number and/or the processing timestamp. For example, the expression `“EDI837-” & $millis()` results in filenames like `EDI837-5182341242`.
## Control numbers
Control numbers are used in the [`ISA` Interchange Control Header](https://www.stedi.com/edi/x12/segment/ISA) and [`GS` Functional Group Header](https://www.stedi.com/edi/x12/segment/GS) of X12 EDI files. You and your trading partners can use them reference EDI files and to detect duplicates and missing data. Control numbers must be unique within a partnership.
Stedi handles control numbers automatically for you. When you create a partnership, Stedi sets the control number counters to `0` for both the Interchange (`ISA`) and Group (`GS`) levels. Each time you send an outbound EDI file, Stedi increments the control numbers to ensure uniqueness.
### Reset control numbers
In rare circumstances, you may need to reset the control numbers for a partnership. For example, if you're migrating from another EDI system, you may need to reset the control numbers to match the last control numbers used in your previous system.
To reset control numbers for outbound documents:
1. Go to the partnership where you want to adjust the control numbers.
2. Open the **Advanced settings** menu.
3. Update the **Interchange** or **Group** control numbers as needed.
### Non-numeric control numbers
Stedi can translate EDI files containing non-numeric control numbers, if required for your use case.
Successful processing requires that you set the `ST-02` and `SE-02` control number elements in the associated Stedi guide to type `String`.
## Timezone and time format
Stedi uses the following default values:
* **Timezone:** UTC | Used in the `ISA` and `GS` segments
* **Time format:** `HHMMSS` | The [GS-05](https://www.stedi.com/edi/x12/segment/GS#GS-05) time element
You can change these values in the partnership's **Advanced settings** menu.
## Next steps
We recommend configuring [Acknowledgments](/edi-platform/configure/trading-partners/functional-acknowledgments) for inbound transactions within the partnership.
We also recommend configuring one or more [webhooks](/edi-platform/configure/webhooks) to automatically send events from Stedi to your internal systems and business applications.
# Configure webhooks
Source: https://www.stedi.com/docs/edi-platform/configure/webhooks/configure-webhooks
***
title: Configure webhooks
sidebarTitle: Configure
-----------------------
Configuring a webhook involves:
* Creating a [credential set](#credential-set) for authentication to the endpoint.
* Creating a [webhook](#webhook) that specifies the URL where Stedi should deliver events.
* Adding one or more [event bindings](#event-bindings) that trigger the webhook.
## Credential set
A credential set defines how to authenticate with a specific API. You can use a single credential set across multiple webhooks. Stedi supports the following types of configurations.
\| Type | Description |
\| ---------- | -------------------------------------------------------------------------------------------------------------------------- |
\| API Keys | The API keys as headers in the request. The most common version is ‘bearer tokens’. |
\| Basic Auth | [HTTP Basic Auth](https://developer.mozilla.org/en-US/Web/HTTP/Authentication), where you provide a username and password. |
\| None | For endpoints that don't require any authentication. |
### Unauthenticated endpoints
When using the 'None' credential set type in webhooks, it's functionally the same as using 'API Keys'. However, we set a dummy value for `Header name` and `Value` (`x-stedi-noauth` and `dummy`). Since the receiving API isn't authenticating the call, it will ignore these values and accept the request.
### Create credential set
You can define a credential set as part of configuring a new webhook. You can also create a new credential set independently and then attach it to one or more webhooks.
To create a credential set:
1. Go to the [Webhooks](https://portal.stedi.com/app/webhooks) page.
2. Click **Manage credentials**, and then click **Create credential set**.
3. Enter a name.
4. Choose the appropriate **Authentication type**.
5. Enter the details.
6. Click **Create credential set**.
## Webhook
A webhook defines which URL endpoint Stedi should call when the webhook is invoked, and which HTTP method to use (`POST`, `PUT`, `GET`, `PATCH`, `DELETE`).
You can only attach one credential set to each webhook. However, you might have multiple webhooks for a single system integration, each with a different endpoint.
### Create webhook
To create a new webhook:
1. Go to the [Webhooks](https://portal.stedi.com/app/webhooks) page.
2. Click **Create webhook**.
3. Enter a name.
4. Choose a **Method** and enter an **Endpoint** URL. This is where Stedi delivers the events when the webhook is invoked.
5. Select a **Credential set** to use for authentication or create a new one for this endpoint.
6. (Optional) Set the **Concurrency**. You can set the maximum number of deliveries that Stedi will attempt to deliver to the endpoint at one time. This can help you avoid overloading the target service.
## Event bindings
Event bindings allow you to specify which events trigger the webhook. You can create multiple event bindings for a single webhook. For example, you may want to create an event binding for each type of transaction you want to send to your API.
### Create event binding
To create a new event binding:
1. Go to the [Webhooks](https://portal.stedi.com/app/webhooks) page.
2. Click the webhook.
3. Click the **Event bindings** tab.
4. Click **New event binding**.
5. Choose an **Event type** and complete the remaining fields. To listen for processed transactions, select **Transaction processed** or **Fragment processed**. Visit [Event types](/edi-platform/operate/event-types) for details about each event.
6. Click **Create binding**.
### Ingest processed transactions
You can use the provided download URLs in the following events to retrieve the processed transaction data from Stedi.
* [Transaction processed events](/edi-platform/operate/event-types#transaction-processed): An EDI file can contain multiple transactions, so a single EDI file can produce multiple events that each invoke the configured webhook.
* [Fragment processed events](/edi-platform/operate/event-types#fragment-processed): When [Fragments](/edi-platform/fragments) are enabled, Stedi emits one fragment processed event for each fragment within the processed transaction.
You may want to configure the following filters for transaction processed or fragment processed events:
1. **Transaction set:** This is useful if you want to send events for different transaction sets to different endpoints. For example, you could send events for 834 benefit enrollments to one endpoint and events for 837 claims to another.
2. **Partnership:** This is useful if you want to send events from different partners to different endpoints. For example, you could send events from processed transactions for each provider to a different endpoint. This is less common.
3. **Guide:** This is useful if you want to send events from transactions parsed using different guides to different endpoints. For example, you may receive `005010` 850 Purchase Orders from two different retailers, and those retailers have different guides. Since the transaction payloads will differ, you may want to send them to different API endpoints within your system.
4. (Optional) You can configure the following **Advanced** settings:
* **Connection:** This is useful when you are using multiple connections for a single partnership. For example, you may have set up one connection type for test data and a separate connection for production data.
* **Mode:** Specify the type of data Stedi is processing. You can choose from **Test** or **Production**.
# Webhooks error handling and limitations
Source: https://www.stedi.com/docs/edi-platform/configure/webhooks/error-handling-webhooks
***
title: Webhooks error handling and limitations
sidebarTitle: Error handling and limitations
--------------------------------------------
[Webhooks](/edi-platform/configure/webhooks/configure-webhooks) have certain limitations. If your system's API has different requirements, you can set the target to be:
* A function, such as AWS Lambda, Google Cloud Functions, or Azure Functions, which can then call the third-party API
* An iPaaS platform, such as Zapier or Workato, which can then call the third-party API.
## HTTP response codes
Stedi considers a `2xx` response a success, and marks any other response as a failure.
Stedi retries events associated with status codes other than `2xx` for up to 4 times with a 90 second wait period inbetween retries.
If the maximum number of retries has been exhausted, Stedi adds the event to the [error queue](#error-queue) for the webhook.
You can set the **Concurrency** when configuring the webhook to prevent throttling. This setting determines the maximum number of deliveries that Stedi will attempt to deliver to the endpoint at one time.
## Certificates
Webhooks only support valid, publicly trusted certificates. Self-signed certificates or certificates from private certificate authorities aren't supported.
You'll receive the following error if the endpoint configured for the webhook uses a certificate that isn't signed by a known, trusted certificate authority:
```
"awsResponse": "Unable to invoke ApiDestination endpoint: API destination endpoint cannot be reached."
```
## Timeouts
The target endpoint must respond with a `2xx` status code within 5 seconds, or the event will be counted as a failed delivery.
This is a hard limit that cannot be increased or configured.
Because of this timeout limitation, we recommend designing your webhook endpoints to immediately acknowledge receipt with a `2xx` response, then process the data asynchronously. See [Best practices for webhook endpoints](#best-practices-for-webhook-endpoints).
## Retries and duplicate deliveries
When a delivery fails, Stedi will retry up to 4 times every 90 seconds. After the fifth retry, Stedi moves the event to the error queue.
If your webhook doesn't respond within 5 seconds, Stedi marks that as a failure and then automatically retries. This can result in duplicate deliveries.
We strongly recommend using idempotency in your webhook receivers to safely handle duplicate deliveries. See [Best practices for webhook endpoints](#best-practices-for-webhook-endpoints).
## Error queue
Each webhook includes an error queue. Each item in the queue consists of the original event that was attempted to be delivered. This ensures if the target service has some downtime, or anything else goes wrong, the missed events can be retried later. The error queue retains items for 14 days.
The order of the error queue is not guaranteed. The downstream service must be designed to be idempotent to handle at-least-once delivery of events, and must accept events out of order.
## Logs
To view logs, click the webhook to go to its detail page, and then navigate to the **Logs** tab.
## Deauthorized connections
If a webhook sends a message to an endpoint that returns a 401 (Unauthorized) response, the destination will be 'deauthorized'. In this state, the webhook won't be able to deliver messages.
If there is an issue with your authentication information (such as the password, API key, or OAuth settings), edit the webhook to fix it.
If the authentication information is correct, and there was a different reason for the endpoint returning a 401, you can try again by adding a temporary header. For example, `x-stedi-reauthorize` with today's date as a value. When you save, the webhook will attempt to deliver again. This header can be removed later. Editing the value of a header will also restart deliveries.
You will likely have a queue of messages to deliver, so Stedi will automatically start retrying them after you make this change. If the endpoint is still returning an invalid response, the webhook will return to `Deauthorized`.
## Best practices for webhook endpoints
When creating endpoints to receive webhooks from Stedi, we recommend the following architecture:
1. **Acknowledge first, process later**: Design your endpoint to immediately return a `2xx` status code to acknowledge receipt, then process the payload asynchronously.
2. **Store payloads for processing**: Capture the webhook data in a queue, database, or other storage mechanism before processing.
3. **Process asynchronously**: Handle the actual business logic in a separate process or worker after acknowledging receipt.
4. **Implement idempotency**: Use idempotency keys from the event payload to prevent duplicate processing.
* Store the `eventId` from each webhook payload in your database
* Before processing an incoming webhook, check if its `eventId` has already been processed
* Design operations to be idempotent, ensuring that processing the same event multiple times doesn't cause issues (e.g., avoid incrementing counters on each processing attempt)
This architecture prevents [timeouts](#timeouts), handles potential duplicate deliveries, and allows you to process high volumes of events.
# Webhooks overview
Source: https://www.stedi.com/docs/edi-platform/configure/webhooks
***
title: Webhooks overview
sidebarTitle: Overview
----------------------
Each time you receive an EDI file from a trading partner, you will want to ingest the transactions into your downstream system for processing. You can do this by configuring a webhook. Webhooks allow you to send events from Stedi to third-party services without writing any custom code.
Stedi can send webhooks to:
* Custom applications using Basic or API Key authorization
* Cloud functions, including AWS Lambda, Google Cloud Functions, and Azure Functions
* iPaaS platforms, such as Zapier, Workato, or Tray.io
* ERPs like NetSuite, SAP, or Oracle.
The most common use case is ingesting processed transaction data into your internal systems and business applications. You can configure a webhook to send `transaction.processed.v2` events to your system and then programatically retrieve the processed transaction data from Stedi using the provided download URL.
You can also configure webhooks for other [Stedi events](/edi-platform/operate/event-types), like when a processing error occurs. This can be used to trigger alerts in systems like Slack, PagerDuty, or Zendesk for further review.
# Common Mapping Expressions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/common-mapping-expressions
***
title: Common Mapping Expressions
sidebarTitle: 'Common Mapping Expressions'
------------------------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
For every field in your target, you need to write an expression that specifies how to turn input fields into an output field. The following example shows how you could output a total price from a quantity and a unit price.
```
{ "total": item.quantity * item.unit_price }
```
Refer to [Mapping Definition](/edi-platform/mappings/manage-mappings/mapping-definition) for more details about mapping components.
This page demonstrates mapping expressions that address common use cases. Refer to the following resources for more examples.
* [Mapping expression cheatsheet][cheatsheet]: A collection of more common patterns for mapping expressions
* [JSONata documentation][jsonata-docs]: A description of the JSONata language
## Basic mapping expressions
You start with a target field and write a mapping expression to select the corresponding source field. The simplest mapping expression points to a single source field.
**Source**
```json
{
"telephone": "+(1)(303) 555-0100"
}
```
**Target**
```json
{
"phone_number": "+(1)(303) 555-0100"
}
```
**Expression**
| Target field | Mapping expression |
| -------------- | ------------------ |
| `phone_number` | `telephone` |
The output will contain the key `phone_number`. In this case, the mapping expression is simply the name of a field in the source.
### Nested source fields
Use a path to select nested source fields
**Source**
```json
{
"business": {
"contact": {
"telephone": "+(1)(303) 555-0100"
}
}
}
```
**Target**
```json
{
"phone_number": "+(1)(303) 555-0100"
}
```
**Expression**
| Target field | Mapping expression |
| -------------- | ---------------------------- |
| `phone_number` | `business.contact.telephone` |
A path contains the key names at every level of a field, separated by dots.
It can be tedious to write out the path for every mapping expression, especially if you have a source with a deeply nested structure. In the Mappings UI, you can click on the field in the source to copy the path to your clipboard.
## Lists
To map a list in the source to a list in the target, you need to take two steps.
1. Write a mapping expression to specify which list you need from the source.
2. Write a mapping expression for each field inside the list of your target.
**Source**
```json
{
"transaction": {
"order": {
"products": [
{
"id": "QL-5490S",
"amount": 17,
"price": {
"unit": 840,
"total": 14280
}
},
{
"id": "LV-69200",
"amount": 91,
"price": {
"unit": 15,
"total": 1365
}
},
{
"id": "RD-0392P",
"amount": 1,
"price": {
"unit": 930,
"total": 930
}
}
]
}
}
}
```
**Target**
```json
{
"orders": [
{
"product_number": "FF08CD",
"quantity": 1,
"unit_price": 20
}
]
}
```
**Expression**
In the target, the list is called `orders`. In the mappings UI, the field is marked with the word **array**, which is another word for list. In the source, the list that contains the relevant data has the path `transaction.order.products`, so that's the mapping expression you need for `orders`.
Specify a mapping expression for each field in `orders`. For example, the field `product_number` is called `id` in the source.
| Target field | Mapping expression |
| ---------------- | ---------------------------- |
| `orders` | `transaction.order.products` |
| `product_number` | `id` |
| `quantity` | `amount` |
| `unit_price` | `price.unit` |
The mapping expressions for the fields in the list don't include `transaction.order.products`, because Mappings knows that those fields are relative to the context of the list. For that reason, the mapping expression for a list is referred to as a *list context*.
### List indexes
If the list entries of your target document are expected to include a list index number, you can access it by binding a *positional variable* to the List Context.
Read about *positional variable binding* in the [JSONata
docs](https://docs.jsonata.org/path-operators#-positional-variable-binding).
For example, imagine you have the same source document as in the previous example, but the target document contains a new `index` property:
**Source**
```json
{
"transaction": {
"order": {
"products": [
{
"id": "QL-5490S",
"amount": 17,
"price": {
"unit": 840,
"total": 14280
}
},
{
"id": "LV-69200",
"amount": 91,
"price": {
"unit": 15,
"total": 1365
}
},
{
"id": "RD-0392P",
"amount": 1,
"price": {
"unit": 930,
"total": 930
}
}
]
}
}
}
```
**Target**
```json
{
"orders": [
{
"product_number": "FF08CD",
"index": 1,
"quantity": 1,
"unit_price": 20
}
]
}
```
**Expression**
To get access to the list index number, you need to define a *positional variable* for your List Context first. Then, you can use it in your mapping expression for the `index` field. Positional variables in JSONata are zero-based.
| Target field | Mapping expression |
| ---------------- | ------------------------------------- |
| `orders` | `transaction.order.products#$myIndex` |
| `product_number` | `id` |
| `index` | `$myIndex + 1` |
| `quantity` | `amount` |
| `unit_price` | `price.unit` |
Once the expression gets evaluated, you can verify that the `index` property is successfully populated for every item in the Output JSON document. This approach could create output like the following example.
```json
{
"orders": [
{
"product_number": "QL-5490S",
"index": 1,
"quantity": 17,
"unit_price": 840
},
{
"product_number": "LV-69200",
"index": 2,
"quantity": 91,
"unit_price": 15
},
{
"product_number": "RD-0392P",
"index": 3,
"quantity": 1,
"unit_price": 930
}
]
}
```
### Lists with one value
If a list contains only one value, it will show up in the output as a single value instead of as a list. Consider the following example.
**Source**
```json
{
"products": [
{
"id": "QL-5490S"
}
]
}
```
**Target**
```json
{
"product_numbers": ["FF08CD", "RX66PL"]
}
```
**Expression**
| Target field | Mapping expression |
| ----------------- | ------------------ |
| `product_numbers` | `products.id` |
You'd expect the output to be a list, just like the target example, but because there's only one product, the result is a single value.
```json
{
"product_numbers": "QL-5490S"
}
```
If you want to make sure that the result is always an array, put `[]` at the end of the mapping expression. The following example shows the new output.
```json
{
"product_numbers": ["QL-5490S"]
}
```
## Objects
In a generic case, to map an object in the source to an object in the target, you don't need to do anything on the object level, you only need to define expressions for each field inside of your target object.
**Source**
```json
{
"product":
{
"id": "QL-5490S",
"amount": 17,
"price": {
"unit": 840,
"total": 14280
}
}
}
}
```
**Target**
```json
{
"order": {
"product_number": "FF08CD",
"quantity": 1,
"unit_price": 20
}
}
```
**Expression**
Specify a mapping expression for each field within the `order` object.
| Target field | Mapping expression |
| ---------------- | -------------------- |
| `order` | |
| `product_number` | `product.id` |
| `quantity` | `product.amount` |
| `unit_price` | `product.price.unit` |
There is no expression specified on the `order` level, so all of its children have to specify a path relative to the root of the source document.
## Object context
Object context is an optional expression that can be provided for any field which contains a single JSON object.
By providing an object context you can improve your mappings in two ways:
1. Avoid repetition of the data transformation within child field expressions.
2. Omit whole objects from the output based on a condition.
### Avoiding repetition within child field expressions
Another way to solve the same mapping from the previous example, would be to provide an *object context* for the `order`, and remove the common part of the path from expressions of its child fields.
| Target field | Mapping expression |
| ---------------- | ------------------ |
| `order` | `product` |
| `product_number` | `id` |
| `quantity` | `amount` |
| `unit_price` | `price.unit` |
Removal of the repeated path prefix was not so dramatic, but imagine you have to map a particular member of an array in the source document, to a single object in the output document.
**Source**
```json
{
"products": [
{
"id": "QL-5490S",
"amount": 17,
"price": {
"unit": 840,
"total": 14280
}
},
{
"id": "LV-69200",
"amount": 91,
"price": {
"unit": 15,
"total": 1365
}
},
{
"id": "RD-0392P",
"amount": 1,
"price": {
"unit": 930,
"total": 930
}
}
]
}
```
**Target**
```json
{
"order": {
"product_number": "FF08CD",
"quantity": 1,
"unit_price": 20
}
}
```
**Expression**
In this example, we are only interested in a product with ID starting with `LV-` prefix.
| Target field | Mapping expression |
| ---------------- | --------------------------------------------- |
| `order` | `products[$startsWith(id, "LV-")] ~> $single` |
| `product_number` | `id` |
| `quantity` | `amount` |
| `unit_price` | `price.unit` |
The mapping expressions for the fields in the list don't include the filter expression, because Mappings knows that those fields are relative to the context of the object. For that reason, the optional mapping expression for an object is referred to as an *object context*.
### Conditionally omitting objects
Mappings allows to skip an object with all of its child fields from the output based on a condition. To achieve that, specify a custom object context that evaluates to an [$omitField constant](#dollaromitfield) when your desired conditions are met.
Let's consider a case, where the source document may contain an array of products of variable length, and if the count of products in the source is `0`, a certain object should not be populated in the output.
**Source**
```json
{
"customer": "John Doe",
"products": [
{
"id": "QL-5490S",
"amount": 17,
"price": {
"unit": 840,
"total": 14280
}
},
{
"id": "LV-69200",
"amount": 91,
"price": {
"unit": 15,
"total": 1365
}
},
{
"id": "RD-0392P",
"amount": 1,
"price": {
"unit": 930,
"total": 930
}
}
]
}
```
**Target**
```json
{
"customer_name": "Jane Doe",
"order": {
"quantity": 1,
"total_price": 20
}
}
```
**Expression**
To omit the `order` object from the output, you should provide a ternary condition as an optional object context, and return `$omitField` when zero products were found in the source.
When the omitting condition is not met, you can pass down the parent context variable `$`, which in this case would evaluate to the whole source document, the same as not providing and object context at all.
| Target field | Mapping expression |
| --------------- | --------------------------------------- |
| `customer_name` | `customer` |
| `order` | `$count(products) = 0 ? $omitField : $` |
| `quantity` | `$count(products)` |
| `total_price` | `$sum(products.price.total)` |
## Advanced mapping expressions
Mappings allows you to do more advanced things than selecting fields. Unless you're an experienced programmer, writing complex mapping expressions will take some getting used to. We'll provide some common patterns here. If you're looking for more, check out our [mapping expressions cheatsheet][cheatsheet].
Advanced mapping expressions can get quite long. Click on the green icon next
to the mapping expression you're editing to open the fullscreen view. This
will give you more space to work with.
### Text to number
Sometimes, your source will have quotes around a number. When that happens, Mappings thinks it's dealing with text. You can convert the text to a number by using the `$number` function.
**Source**
```json
{
"quantity": "8"
}
```
**Target**
```json
{
"quantity": 8
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | ------------------- |
| `quantity` | `$number(quantity)` |
### Number to text
If your target contains a number in quotes, then to Mappings, that's text instead of a number. You can convert the number to text by using the `$string` function. String is another word for text.
**Source**
```json
{
"quantity": 8
}
```
**Target**
```json
{
"quantity": "8"
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | ------------------- |
| `quantity` | `$string(quantity)` |
### Calculations
You can do calculations on numbers using `*`, `/`, `+`, and `-`.
**Source**
```json
{
"price": 500,
"quantity": 8,
"discount": 150
}
```
**Target**
```json
{
"total": 3850
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | ----------------------------- |
| `total` | `price * quantity * discount` |
If the numbers in the source are surrounded by quotes, you need to convert them first using the `$number` function.
**Source**
```json
{
"subtotal": "500",
"vat": "10"
}
```
**Target**
```json
{
"total": 510
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | ---------------------------------- |
| `total` | `$number(subtotal) * $number(vat)` |
### Sum and average
You can calculate the sum and average of a list of numbers using `$sum` and `$average`.
**Source**
```json
{
"prices": [14280, 1365, 930]
}
```
**Target**
```json
{
"sum": 16575,
"average": 5525
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | ------------------ |
| `sum` | `sum(prices)` |
| `average` | `average(prices)` |
Often, the numbers you're interested in are part of a more complex structure.
**Source**
```json
{
"orders": [
{
"product_id": "QL-5490S",
"price": 14280
},
{
"product_id": "LV-69200",
"price": 1365
},
{
"product_id": "RD-0392P",
"price": 930
}
]
}
```
**Target**
```json
{
"sum": 16575,
"average": 5525
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | -------------------------- |
| `sum` | `$sum(orders[].price)` |
| `average` | `$average(orders[].price)` |
In this case, you can refer to the field you're interested in by its full path (`price`). Make sure to put `[]` after the name of the list (`orders`) to let Mappings know that you want all prices in the list.
### Putting text together
When you have to two text fields and you want to put them together, you can use `&`.
**Source**
```json
{
"first_name": "Alice",
"last_name": "Mahara"
}
```
**Target**
```json
{
"name": "Alice Mahara"
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | ------------------------------ |
| `name` | `first_name & " " & last_name` |
### Taking text apart
You can extract a small part out of a text by using `$substring`. You need to specify where the part is that you're interested in, so this only works for text that follows a predictable pattern.
**Source**
```json
{
"phone_number": "(303) 555-0100"
}
```
**Target**
```json
{
"area_code": "303"
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | ------------------------------- |
| `area_code` | `substring(phone_number, 1, 3)` |
The two numbers let `$substring` know where the part begins, and how many letters you want. `$substring` starts counting characters at 0, so in the example above, we start at the second characters.
If the part you're interested in is at the back of the text, you can use a negative number to tell `$substring` to start counting from the last character.
**Source**
```json
{
"phone_number": "(303) 555-0100"
}
```
**Target**
```json
{
"local_number": "555-0100"
}
```
**Expression**
| Target field | Mapping expression |
| -------------- | --------------------------------- |
| `local_number` | `$substring(phone_number, -8. 8)` |
### Splitting text
Sometimes a text contains multiple pieces of data, separated by a character. You can turn the text into a list using `$split`.
**Source**
```json
{
"location": "Chicago, Illinois, United States"
}
```
**Target**
```json
{
"location": ["Chicago", "Illinois", "United States"]
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | ------------------------ |
| `location` | `$split(location, ", ")` |
You can assign each item in the list to a field by using an *index*, which is a number between square brackets. Items in a list are numbered starting at 0.
**Source**
```json
{
"location": "Chicago, Illinois, United States"
}
```
**Target**
```json
{
"city": "Chicago",
"state": "Illinois",
"country": "United States"
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | --------------------------- |
| `city` | `$split(location, ", ")[0]` |
| `state` | `$split(location, ", ")[1]` |
| `country` | `$split(location, ", ")[2]` |
### Lookup table
If you have a field that contains a code that you want to replace with a related value, you can build a lookup table.
**Source**
```json
{
"country_code": "USA"
}
```
**Target**
```json
{
"country": "United States"
}
```
Before you can write a mapping expression for this, you'll need to create the lookup table.
1. Clicking the edit icon next to the mapping expression.
2. Click **Lookup tables** and select **Add new**.
3. Enter values for your table. You can add values manually, or load them from CSV.
Now you can use the lookup table in your mapping expressions using the function `$lookupTable`. For example, you might create a lookup table for country codes and then write the following expression.
| Target field | Mapping expression |
| -------------- | ------------------------------------------------------------ |
| `country_code` | `$lookupTable($tables.countries, "short" country_code).long` |
A lookup table isn't limited to two values per entry; a row can have as many values as you need. For example, you could create a currency lookup table with two columns: `code` for the country code and `symbol` for the currency symbol.
**Source**
```json
{
"currency": "USD"
}
```
**Target**
```json
{
"currency": {
"name": "U.S. Dollar",
"symbol": "$"
}
}
```
**Expression**
| Target field | Mapping expression |
| ------------ | --------------------------------------------------------- |
| `name` | `$lookupTable($tables.currency, "code", currency).name` |
| `symbol` | `$lookupTable($tables.currency, "code", currency).symbol` |
### Lookup table wildcards
You can use Lookup Tables and wildcards for matching multiple possible input options at once.
In your lookup table, replace the interchangeable part of the key you want to match against with the `*` symbol (or any other sequence of symbols, you will be able to select what to match against during the `$lookupTable` function call).
-> **Note:** You can replace multiple parts of your key with `*`.
Any input value that matches the loosely defined wildcard-based lookup table value is now matched when the `{ "wildcard": "*" }` is passed as an optional parameter to the `$lookupTable` function.
## Mapping types
The mapping type specifies how the Mappings API generates the output field when the mapping expression doesn't produce a value. A mapping expression may not produce a value when one or more of the input fields that the mapping expression depends on aren't present.
You can choose between the following mapping types:
* Only mapped keys
* Merge with target example
* Pass through
Visit [Mapping Definition Overview](/edi-platform/mappings/manage-mappings/mapping-definition#mapping-types) for full details and examples of how the Mappings UI generates outputs in each case.
## Omitting output fields
There are times when a field is present in the target, but you don't want it to end up in the output. You have two options.
* Deselect the target field.
* Use the `$omitField` constant.
### Deselecting target fields
If you don't provide a mapping expression for a target field, or if a mapping expression doesn't produce a result, the field may still end up in the output. If you don't want that, you can deselect the target field.
In the following example, none of the fields in the `totals` object has a mapping expression associated with it, but it still ends up in the output.
**Target**
```json
{
"products": [
{
"id": "FF08CD"
}
],
"totals": {
"quantity": 3,
"price": 8850
}
}
```
| Target field | Mapping expression |
| ------------ | ------------------ |
| `products` | `products` |
| `id` | `id` |
| `quantity` | |
| `price` | |
**Output**
```json
{
"products": [
{
"id": "QL-5490S"
}
],
"totals": {}
}
```
If you don't want `totals` to show up at all, select **Target keys** and deselect the field.
This doesn't apply when you set the mapping type to *Merge with target example*, because that option will always copy the values from the the target, unless you use `$omitField`.
### $omitField
Whether a target field should end up in the output is not always a simple yes-or-no question. Sometimes, it depends on the result of the mapping expression. In that case you can use `$omitField` to tell Mappings when to skip the field.
This is particularly useful if the mapping type is set to *Merge with target example* and you don't want to use the default value. In the following example, the total price is included only if the amount of products is larger than 0.
**Target**
```json
{
"totalPrice": 3000,
"unitPrice": 150
}
```
**Mapping Expression**
| Target field | Mapping expression |
| ------------ | ------------------------------------------ |
| `totalPrice` | `amount > 0 ? amount * price : $omitField` |
| `unitPrice` | `price` |
**Input**
```json
{
"price": 150,
"amount": 0
}
```
**Output**
```json
{
"unitPrice": 150
}
```
Without `$omitField`, the output would've included the `totalPrice` with its default value of `3000`, which is clearly wrong in this case.
You can use `$omitField` in any input field on the Mapping form, including
[list context](#lists) and [object context](#object-context) inputs.
[mappings-product]: https://stedi.com/app/mappings
[edi-translate-docs]: /legacy/edi-core#translation
[cheatsheet]: /mappings/jsonata/jsonata-cheatsheet
[jsonata-docs]: https://docs.jsonata.org/overview
# JSONata Cheatsheet
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-cheatsheet
***
## title: JSONata Cheatsheet
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
All mappings expressions are based on [JSONata language](http://docs.jsonata.org/overview.html) - this page showcases its most important features useful when creating a mapping.
## 1. JSON object source document
The source for each example is derived from the following JSON:
```json
{
"senderName": "STEDI",
"customerID": "997321",
"shipmentID": 3312412,
"shipment type": "ASAP",
"address": {
"street": "1234 Main St.",
"city": "Los Angeles",
"state": "CA",
"country name": "USA",
"is-europe": false
},
"orders": [
{
"orderDate": "2021/03/17",
"productID": "DEG32",
"quantity": 3,
"pricePerUnit": 5,
"volume": "10"
},
{
"orderDate": "2021/10/12",
"productID": "OIU98",
"quantity": 100,
"pricePerUnit": 1,
"volume": "15"
},
{
"orderDate": "2021/01/07",
"productID": "PWE47",
"quantity": 45,
"pricePerUnit": 500,
"volume": "35"
}
]
}
```
### 1.1 Retrieving data
#### Root-level field
#### Nested field in the root object
#### Nested field with a dash in its name in the root object
#### Nested field in a root level array
#### Retrieve an array of items from a root level array
#### Retrieve a root-level field with whitespace in its key
#### Retrieve a nested field with whitespace in its key
### 1.2 Operating on data
#### Concatenate two strings, separated by a space
#### Multiply two values retrieved from an array together
It is not recommended to use JSONata for floating point arithmetic, such as
financial calculations. Floating-point arithmetic can introduce rounding
errors, which can accumulate and lead to incorrect results. Visit our [JSONata
Playground](https://stedi.link/UKXfsxe) for an example. We recommend
representing monetary values as integers (e.g. cents) and performing
calculations on those integers.
(`[-1]` retrieves the last item in an array)
#### Remove a given character from a string
#### Convert a value to a string
(`$string` is a [JSONata
function](/edi-platform/mappings/jsonata/jsonata-functions/string#dollarstring))
#### Convert a value to a number
(`$number` is a [JSONata
function](/edi-platform/mappings/jsonata/jsonata-functions/numeric#dollarnumber))
### 1.3 String manipulation
#### Convert a value to a lowercase string
#### Convert a value to an uppercase string
#### Truncate a string to only the first 4 characters
#### Check if a string contains a given substring
#### Get all characters in a string after a given substring
#### Replace all `/`s with `-` in a string
#### Replace all `/`s with `-` in in a string (using `~>` operator)
### 1.4 Conditionals
#### Use a conditional to return a value based on a condition
#### Use a conditional with a function to return a value based on a condition
### 1.5 Filtering data
#### Filter data if a given value is greater than N
#### Filter data if a given value is equal to X
#### Filter data based on a complex condition
The `[]` is required at the end of an expression to convert the result to an
array.
### 1.6 Counting data
#### Count fields based on a greater-than filter expression
#### Count fields based on a substring value filter expression
#### Count fields based on a substring value with `~>` operator
#### Add up all values in an array
#### Add up all values in an array with `~>` operator
It is not recommended to use JSONata for floating point arithmetic, such as
financial calculations. Floating-point arithmetic can introduce rounding
errors, which can accumulate and lead to incorrect results. Visit our [JSONata
Playground](https://stedi.link/UKXfsxe) for an example. We recommend
representing monetary values as integers (e.g. cents) and performing
calculations on those integers.
#### Use `$map`, `$sum` and `~>` operator to add up all values in an array
[$map](/edi-platform/mappings/jsonata/jsonata-functions/higher-order#dollarmap)
is used to convert all items in `orders.volume` array to a
[$number](/edi-platform/mappings/jsonata/jsonata-functions/numeric#dollarnumber).
### 1.7 Variables
In JSONata, any name that starts with a `$` is a variable (e.g. `$streetName := address.street`). A variable can be one of any type in JSONata's [type system](https://docs.jsonata.org/processing#the-jsonata-type-system).
#### Built-in variables
* `$` – the variable with no name refers to the context value at any point in the input JSON hierarchy.
* `$$` – the root of the input JSON. You can use it to break out of the current context and navigate down a different path.
#### Convert a list of fields to the desired format using the built-in `$` variable
#### Populate an object field using the built-in `$$` variable for every item while looping over an array
#### Convert value to a string and store it in a variable
`$variableName := value` is how assigns `value` to a JSONata `$variableName`
variable
#### Count all items in an array and return a different result based on its size
A multi-line expression needs to be wrapped in `()`
#### Multiply values across all items in an array and return a boolean flag based on the result
#### Positional variables
[Positional variables binding](https://docs.jsonata.org/path-operators#-positional-variable-binding) can be used to determine at which position in the sequence the current context item is. It can be used following any map, filter or order-by stage in the path.
The variable is available for use within subsequent stages of the path (e.g. within filter predicates or a map operation) and goes out of scope at the end of the path expression.
#### Populate order title based on its index within the orders array
### 1.8 Dates
#### Get the current date & time in ISO 8601 format
#### Get the current date & time in 6-character EDI date format
#### Get the current date & time in 8-character EDI date format
#### Convert a date from `yyyy/MM/dd` format to `DD/MM/YYYY`
#### Get the month given a date in `yyyy/MM/dd` format
#### Convert a date taken from an array from `yyyy/MM/dd` format to `DD-MM-YYYY`
#### Convert epoch date to EDI date format
#### Convert given UTC date to `America/New_York` timezone
## 2. JSON array-of-objects source document
The source for each example is derived from the following JSON:
```json
[
{
"orderDate": "2021/10/12",
"productID": "OIU98",
"quantity": 100,
"pricePerUnit": 1,
"address": {
"street": "1234 Main St.",
"city": "Los Angeles",
"state": "CA",
"country name": "USA",
"is-europe": false
}
},
{
"orderDate": "2021/01/07",
"productID": "PWE47",
"quantity": 45,
"pricePerUnit": 500,
"address": {
"street": "La Rambla",
"city": "Barcelona",
"state": "Barcelona",
"country name": "Spain",
"is-europe": true
}
}
]
```
### 2.1 Retrieving data
#### Retrieve a field from the first item of a root-level array
#### Retrieve an array of fields from a root-level array
#### Retrieve a nested value from a root-level array
#### Retrieve a value with a space in its key from a root-level array
### 2.2 Operating on data
The data operations expressions operate on the same basis as for the [JSON object source documents](#12-operating-on-data).
### 2.3 String manipulation
The string manipulation expressions operate on the same basis as for the [JSON object source documents](#13-string-manipulation).
### 2.4 Conditionals
The conditionals expressions operate on the same basis as for the [JSON object source documents](#14-conditionals).
### 2.5 Filtering data
The data filtering expressions operate on the same basis as for the [JSON object source documents](#15-filtering-data).
Instead of selecting an array field, you can select the root array with the `$$` selector.
#### Get an array of all items based on a filter expression
### 2.6 Counting data
The data counting expressions operate on the same basis as for the [JSON object source documents](#16-counting-data).
Instead of selecting an array field, you can select the root array with the `$$` selector.
#### Count all items in an array based on a greater-than filter expression
#### Count all items in an array based on a substring filter expression
`$substring(orderDate, 0, 4)` returns first four characters of a string)
#### Count all items in an array based on a substring filter expressions using `~>` operator
#### Sum up all items in an array
#### Sum up all items in an array based on a filter expression
#### Use `$map`, `$sum` and `~>` operator to add up all values in an array
### 2.7 Variables
Variables operate on the same basis as for the [JSON object source documents](#17-variables).
### 2.8 Dates
The dates expressions operate on the same basis as for the [JSON object source documents](#18-dates).
# JSONata Playground
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-playground
***
## title: JSONata Playground
[JSONata Playground](https://www.stedi.com/jsonata/playground) is a website that allows you to play around with [JSONata](https://jsonata.org) in a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)-like environment. You can learn more about the JSONata Playground by reading [this launch blog post](https://www.stedi.com/blog/jsonata-playground).
## Embedding the JSONata Playground into a website
### Good to know
The code snippet used for embedding the [JSONata Playground website](https://www.stedi.com/jsonata/playground) in an `iframe` will render the panels using a **horizontal layout** no matter the width of the parent site container.
### Guide
1. Navigate to the [JSONata Playground website](https://www.stedi.com/jsonata/playground).
2. **(Optional)**: change the contents of the *Source*/*JSONata* panels.
3. Click on the *"Embed"* button.

4. **(Optional)**: Click on the *"Size settings"* button to modify the heights of the individual panels and the total height of the embedded widget.

4.1. Specify the total height (required) and, optionally, each individual panel height. Feel free to experiment with different height values to ensure the widget displays correctly where it is embedded.

5. Click on the *"Copy code"* button.

6. Paste the copied code snippet where you would like to embed the JSONata Playground.
# Manage mapping definitions with the API
Source: https://www.stedi.com/docs/edi-platform/mappings/manage-mappings/api-guide
***
title: Manage mapping definitions with the API
sidebarTitle: 'Mappings API'
----------------------------
Please [contact us](https://www.stedi.com/contact) if you need access to this
feature.
This page explains how to use the Mappings API to create, read, update, and delete Stedi mapping definitions. You can also do these actions in the [Mappings UI](/edi-platform/mappings/manage-mappings/ui-guide).
Before you begin, we recommend reviewing the [Mapping Definition Overview](/edi-platform/mappings/manage-mappings/mapping-definition).
## Create a mapping definition
You create a mapping definition by POSTing to `https://mappings.us.stedi.com/2021-06-01/mappings`. At the very least, your mapping definition should have a name, mapping type, and a few mapping expressions.
```http
POST https://mappings.us.stedi.com/2021-06-01/mappings HTTP/1.1
"Authorization: ${STEDI_API_KEY}"
Content-Type: application/json
{
"name": "A minimal example",
"type": "only_mapped_keys",
"mapping": "{ \"total\": item.quantity * item.unit_price }"
}
```
The mapping expressions look like JSON, but they're not. JSONata has all kinds of syntax that isn't valid JSON. That's why you need to provide the mapping expressions inside of a string.
### Include a target example
If you want to use the mapping type *Merge with target example*, then you need to provide a target example. You do this by including a target schema that contains the target example. The following mapping definition provides a default value of `0` for the output field `total`.
```http
POST https://mappings.us.stedi.com/2021-06-01/mappings HTTP/1.1
"Authorization: ${STEDI_API_KEY}"
Content-Type: application/json
{
"name": "A target example example",
"type": "merge_with_target_example",
"mapping": "{ \"total\": item.quantity * item.unit_price }",
"target": {
"name": "target.json",
"type": "jsonschema@2020-12",
"content": "{\"$schema\": \"https://json-schema.org/draft/2020-12/schema\", \"default\": {\"total\": 0 }}"
}
}
```
The target schema needs to be passed inside a string. That makes the above example a bit hard to read, so here's the target schema with more sane formatting.
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"default": {
"total": 0
}
}
```
### Include a lookup table
You can add one or more lookup tables by providing the `lookup_tables` field. Every lookup table must have a name and a set of values.
```http
POST https://mappings.us.stedi.com/2021-06-01/mappings HTTP/1.1
"Authorization: ${STEDI_API_KEY}"
Content-Type: application/json
{
"name": "A lookup table example",
"type": "only_mapped_keys",
"mapping": "{ \"country\": $lookupTable($tables.countries, \"german\", land).english }",
"lookup_tables": [
{
"name": "countries",
"values": [
{
"english": "United States",
"spanish": "Estados Unidos",
"german": "Vereinigte Staaten"
},
{
"english": "Mexico",
"spanish": "México",
"german": "Mexiko"
},
{
"english": "Germany",
"spanish": "Alemania",
"german": "Deutschland"
}
]
}
]
}
```
### Response
The response contains a copy of the mapping definition you just created, plus a couple of extra fields.
| Field | Description |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id` | The unique identifier for your mapping definition. You need this if you ever want to update, delete, or use your mapping definition. |
| `created_at` | A timestamp indicating when you created this mapping definition. |
| `updated_at` | A timestamp indicating when you last updated this mapping definition. If you've never updated the mapping definition, this is the same as created\_at. |
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "01AB3DEF4GHIJ5KL67MNOP8QR9",
"name": "A minimal example",
"type": "only_mapped_keys",
"mapping": "{ \"total\": item.quantity * item.unit_price }"
"created_at": "2022-01-01T20:22:01.01Z",
"updated_at": "2022-01-01T20:22:01.01Z"
}
```
## Retrieve a mapping definition
You retrieve a mapping definition by GETting it from `https://mappings.us.stedi.com/2021-06-01/mappings/mapping_id`. The response is identical to the one you received when you created the mapping definition. In other words, it's the mapping definition as you specified it, supplemented with the fields `id`, `created_at`, and `updated_at`.
## Update a mapping definition
You update a mapping definition by PUTting a new version at `https://mappings.us.stedi.com/2021-06-01/mappings/mapping_id`. You need to specify an entire new mapping definition, so when we talk about updating the mapping definition, we really mean replacing it.
Other than that, updating a mapping definition is the same as creating one: the request body is the same, the response body is the same.
## Delete a mapping definition
You delete a mapping definition by DELETEing it at `https://mappings.us.stedi.com/2021-06-01/mappings/mapping_id`. That's all there is to it, really. You don't need to provide a request body and the response will be empty as well.
## List mapping definitions
You retrieve a list of all your mapping definitions by GETting it from `https://mappings.us.stedi.com/2021-06-01/mappings`.
```http
GET https://mappings.us.stedi.com/2021-06-01/mappings HTTP/1.1
"Authorization: ${STEDI_API_KEY}"
```
The response has a field `mappings` which contains a list with mapping definitions.
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"mappings": [
{
"id": "01AB3DEF4GHIJ5KL67MNOP8QR9",
"name": "A minimal example",
"type": "only_mapped_keys",
"created_at": "2022-01-01T20:22:01.01Z",
"updated_at": "2022-01-01T20:22:01.01Z"
},
{
"id": "02JK3LMN4OPQR5ST67UVWX8YZ9",
"name": "A target example example",
"type": "merge_with_target_example",
"created_at": "2022-01-01T20:22:01.01Z",
"updated_at": "2022-01-01T20:22:01.01Z"
}
]
}
```
### Rate limit
This endpoint is rate-limited to 25 requests per second, per Stedi account.
### Metadata
The list in the response doesn't contain complete mapping definitions; only metadata. It includes the fields `id`, `name`, `type`, `created_at`, and `updated_at`, but not the mapping expressions or the schema. If you're only displaying a list of mapping definitions, this is typically what you want, but should you need the full mapping definitions, you can set the query parameter `metadata_only` to `false`.
```http
GET https://mappings.us.stedi.com/2021-06-01/mappings?metadata_only=false HTTP/1.1
"Authorization: ${STEDI_API_KEY}"
```
The response will now include the mapping expressions and the schemas.
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"mappings": [
{
"id": "01AB3DEF4GHIJ5KL67MNOP8QR9",
"name": "A minimal example",
"type": "only_mapped_keys",
"mapping": "{ \"total\": item.quantity * item.unit_price }"
"created_at": "2022-01-01T20:22:01.01Z",
"updated_at": "2022-01-01T20:22:01.01Z"
},
{
"id": "02JK3LMN4OPQR5ST67UVWX8YZ9",
"name": "A target example example",
"type": "merge_with_target_example",
"mapping": "{ \"total\": item.quantity * item.unit_price }",
"target": {
"name": "target.json",
"type": "jsonschema@2020-12",
"content": "{\"$schema\": \"https://json-schema.org/draft/2020-12/schema\", \"default\": {\"total\": 0 }}"
},
"created_at": "2022-01-01T20:22:01.01Z",
"updated_at": "2022-01-01T20:22:01.01Z"
}
]
}
```
### Paging
If you have a lot of mapping definitions, you may not receive them all in one response. In that case, the response will contain a field `next_page_token`.
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"mappings": [
...
],
"next_page_token": "0t1H23ER4e5ArEMORE6REsU78l_TSyET"
}
```
You can make another request passing the value of that field to the query parameter `page_token` and you will receive the next few mapping definitions.
```http
GET https://mappings.us.stedi.com/2021-06-01/mappings?page_token=0t1H23ER4e5ArEMORE6REsU78l_TSyET HTTP/1.1
"Authorization: ${STEDI_API_KEY}"
```
As long as the field `next_page_token` shows up in the response, there are more mapping definitions to retrieve.
# Mapping Definition Overview
Source: https://www.stedi.com/docs/edi-platform/mappings/manage-mappings/mapping-definition
***
title: Mapping Definition Overview
sidebarTitle: "Mapping Definition"
----------------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
A mapping definition describes how to turn input JSON into output JSON. It consists of several parts.
* A set of mapping expressions, describing how to transform input fields to output fields
* A mapping type, specifying how output fields are determined
* A target example, providing default values for output fields
* A set of schemas, describing what the input and output JSON should look like
* Lookup tables, to make converting values in mapping expressions easier
You must create a mapping definition for each JSON document type you want to transform. Then, you can use mapping definitions with the Mappings API to [transform JSON documents](/edi-platform/mappings/transform-json-documents) from one shape into another.
You can create mapping definitions with either the [Mappings UI](/edi-platform/mappings/manage-mappings/ui-guide) or the [Mappings API](/edi-platform/mappings/manage-mappings/api-guide).
## Mapping expressions
A mapping expression is a piece of code that specifies how to turn input fields into an output field. The following example shows how you could output a total price from a quantity and a unit price.
```
{ "total": item.quantity * item.unit_price }
```
On the left is the name of the output field, on the right is the mapping expression, written in [JSONata](https://docs.jsonata.org/overview.html). You can add more output fields, separated by commas.
```
{ "total": item.quantity * item.unit_price, "currency": item.currency, "product": product.id }
```
The result looks just like JSON, even though it technically isn't, because of the syntax of JSONata.
Refer to [Write Mapping
Expressions](/edi-platform/mappings/jsonata/common-mapping-expressions) for
full details, examples, and JSONata resources.
## Mapping types
All mapping types produce output fields based on the mapping expressions.
The mapping type specifies how the Mappings API generates the output field when the mapping expression doesn't produce a value. A mapping expression may not produce a value when one or more of the input fields that the mapping expression depends on aren't present.
### Only mapped keys
By default, Mappings adds the target keys you selected to the output and nothing else.
The mappings API handles output fields in the following ways:
* Adds an output field for every mapping expression that returns a result
* Does not add output fields based on the target example
* Does not add output fields based on the input.
Consider the following mapping expression.
```
{ "currency": item.currency, "total": item.quantity * item.unit_price }
```
You provide the following input.
```json
{
"item": {
"unit_price": 2.5,
"currency": "USD"
}
}
```
The Mappings API produces the following output.
* The field `currency` is added to the output because there is a mapping expression for `currency` that produces a result.
* The field `total` is not added to the output. There is a mapping expression for `total`, but it doesn't produce a result because `item.quantity` is missing from the input.
* The fields `item.unit_price` and `item.currency` are not added to the output, because there are no mapping expressions for them.
```json
{
"currency": 5
}
```
### Merge with target example
If you need to produce JSON based on a template, and you only need to change a handful of fields, it's easier if you copy the entire target to the output and only make those few changes. For example, you may want to use a default currency for your output.
The mappings API handles output fields in the following ways:
* Adds an output field for every mapping expression that returns a result
* Copies an output field from the target example, unless that output field was already added because of a mapping expression.
* Does not add output fields based on the input.
Consider the following mapping expressions.
```
{ "unit_price": item.price, "quantity": item.quantity, "total": item.quantity * item.price }
```
You use these expressions with the following target example.
```json
{
"currency": "USD",
"quantity": 1,
"unit_price": 0
}
```
You provide the following input.
```json
{
"item": {
"price": 2.5
}
}
```
The Mappings API produces the following output.
* The field `currency` is copied from the target example because there is no mapping expression for `currency`.
* The field `unit_price` is not copied from the target example, because there is a mapping expression for `unit_price` that produces a result.
* The field `quantity` is copied from the target example. There is a mapping expression for `quantity`, but that one doesn't produce a result, because `item.quantity` is missing from the input.
* The field `total` doesn't end up in the output. There's a mapping expression for `total`, but it doesn't produce a result and the target example doesn't contain a default value for `total`.
```json
{
"currency": "USD",
"unit_price": 2.5,
"quantity": 1
}
```
### Pass through
If your output needs to be much like your input, but with a few values changed, then you can tell Mappings to start with a copy of your input.
The mappings API handles output fields in the following ways:
* An output field will be added for every mapping expression that returns a result.
* An output field will be copied from the input, unless that output field was already added because of a mapping expression.
* No output fields will be added based on the target example.
Consider the following mapping expressions.
```
{
"item": { "quantity": item.quantity * items_per_unit },
"tax_rate": tax_rate < 1 ? tax_rate + 1 : tax_rate,
"total": item.quantity * item.price
}
```
You provide the following input.
```json
{
"item": {
"quantity": 5,
"price": 2.5,
"currency": "USD"
},
"tax_rate": 0.06
}
```
The Mappings API produces the following output.
* All fields are copied from the input.
* The field `tax_rate` is overwritten because there is a mapping expressions for `tax-rate` that produces a result.
* The field `item.quantity` is not overwritten. There is a mapping expressions for `item.quantity` , but it doesn't produce a result, because `items_per_unit` is missing from the input.
* The field `total` is added, because there's a mapping expression for `total` that produces a result.
```json
{
"item": {
"quantity": 5,
"price": 2.5,
"currency": "USD"
},
"tax_rate": 1.06,
"total": 12.5
}
```
## Target example
The target example is a JSON object that provides default values in case a mapping expression doesn't return a result. For example, the following target example sets the default currency to `USD`.
```json
{
"default": {
"currency": "USD"
}
}
```
If the mapping expression can't determine the currency—for example because the input document doesn't contain currency information—then it uses the default from the target example. For this to work, the mapping type must be set to *Merge with target example*. Any other mapping type completely ignores the target example. Also, if you set the mapping type to *Merge with target example*, you must provide a target example. It can be empty, but it must be part of the mapping definition.
The target example is part of the target schema.
## Schemas
The Mappings UI uses the source and target schemas are used by the Mappings UI. If you don't plan on using the Mappings UI—i.e. you'll use the API exclusively—then you generally don't need to provide schemas. The only exception is when you want to provide [default values for your output fields](#target-schema).
Any schema you specify must be a valid [JSON Schema](http://json-schema.org/understanding-json-schema/) (version 2020-12). Also, each schema needs to be self-contained, so you can't include references to external schemas.
### Source schema
The Mappings UI uses the source schema to show an example of an input document. You can use this example to find and select the input fields you need in your mapping expressions. The following schema specifies three input fields: `quantity` , `unit_price` and `currency`.
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"quantity": {
"type": "number"
},
"unit_price": {
"type": "number"
},
"currency": {
"type": "string",
"minLength": 3,
"maxLength": 3
}
}
}
```
Just the schema isn't enough. You also need to provide some values for those fields. The Mappings UI uses the values to show what the output of a mapping expression will be like while you are crafting that expression, which is a useful feature. You can add values to the example by extending the source schema with a default document.
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"quantity": {
"type": "number"
},
"unit_price": {
"type": "number"
},
"currency": {
"type": "string",
"minLength": 3,
"maxLength": 3
}
},
"default": {
"quantity": 15,
"unit_price": 2.5,
"currency": "CAD"
}
}
```
### Target schema
The Mappings UI uses the target schema to show an example of an output document. You can only create mapping expressions for fields that are included in the target schema, so without a target schema, you can't use the Mappings UI. The following schema specifies two output fields: `total` and `currency`.
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"total": {
"type": "number"
},
"currency": {
"type": "string",
"minLength": 3,
"maxLength": 3
}
}
}
```
As with the source schema, you can add a default document to your target schema. Unlike with the source schema, this doesn't help with writing mapping expressions. However, if you want to provide default values for your output fields, adding a default document to your target schema is the way to do that. The following example sets the default currency to `USD`.
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"total": {
"type": "number"
},
"currency": {
"type": "string",
"minLength": 3,
"maxLength": 3
}
},
"default": {
"currency": "USD"
}
}
```
Default values only work if you set the mapping type to *Merge with target example*.
## Lookup tables
A lookup table helps the Mappings API convert a value from one representation to another. For example, the following table allows you to translate country names.
| english | spanish | german |
| ------------- | -------------- | ------------------ |
| United States | Estados Unidos | Vereinigte Staaten |
| Mexico | México | Mexiko |
| Germany | Alemania | Deutschland |
There's no primary key in a lookup table. You can freely translate from English to Spanish, from Spanish to German, from German to English; any direction you want. You specify this in the mapping expression using the `$lookupTable` function. The following example uses the lookup table called `countries` to translate the input field `land` (which is German for *country*) from German to English.
```
{
"country": $lookupTable($tables.countries, "german", land).english
}
```
The following example shows the same `countries` lookup table in JSON.
```json
[
{
"english": "United States",
"spanish": "Estados Unidos",
"german": "Vereinigte Staaten"
},
{
"english": "Mexico",
"spanish": "México",
"german": "Mexiko"
},
{
"english": "Germany",
"spanish": "Alemania",
"german": "Deutschland"
}
]
```
# Mappings UI Builder
Source: https://www.stedi.com/docs/edi-platform/mappings/manage-mappings/ui-guide
***
title: "Mappings UI Builder"
sidebarTitle: "UI Builder"
--------------------------
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
[mappings-product]: https://stedi.com/app/mappings
[disconnect-a-guide]: #disconnect-a-guide
[pull-changes-from-a-guide]: #pull-changes-from-a-guide
You can create and edit mapping definitions with Stedi's visual mapping builder. Before you begin, we recommend reviewing the [Mapping Definitions Overview](/edi-platform/mappings/manage-mappings/mapping-definition).
## Create a mapping
Go to the [Mappings](https://portal.stedi.com/app/mappings) page in your Stedi account and click **Create mapping**. We recommend using the quickstart guide to create a mapping that matches your use case.
## Publish updates
You can edit a mapping at any time, unless it is [locked](#lock-a-mapping).
1. Go to the [Mappings](https://portal.stedi.com/app/mappings) page to review a list of existing mappings in your account. Stedi displays which mappings have unpublished changes.
2. Click a mapping's name to go to the Mappings builder and make updates. Stedi autosaves your changes as you work.
3. Click **Publish** to promote your changes to production.
It takes up to 15 seconds for Stedi to start applying changes you publish to your mappings.
## Lock a mapping
When you're finished editing, you can lock a mapping to prevent further updates. Locking helps prevent accidental changes or deletions to mappings in production.
Don't lock a mapping unless you're sure you don't need to make any additional
changes. Once you lock a mapping, only an account admin can unlock it.
To lock a mapping, open it, click the **...(elipses)** menu next to its name, and select **Lock settings**.
You can choose to lock the entire mapping, or just the mapping definition. When you lock the mapping definition only, you can still add or edit lookup tables, but you cannot edit the mapping source schema, target schema, or mapping expressions. This approach can be helpful when you expect to occasionally receive a new category of data for an existing field - for example, you need to update an existing lookup table with a new partner code or a new line of product SKUs.
No one can update or delete a locked mapping. However, you can duplicate locked mappings, if needed.
## Compare or roll back versions
You can compare the current version of a mapping with any previously published version to see what has changed. You can also roll back to a previous version of a mapping.
Open the **Actions** menu, and select **Version history** to review a list of every published version of the mapping. You can publish an older version or compare it with the current one. Comparing highlights every difference between the old version and the current version, similar to how GitHub displays changes on pull requests.
## Delete a mapping
Once you delete a mapping, you cannot recover its data.
To delete a mapping, click the ellipses (`...`) next to the mapping you want to delete, click **Delete**, and then confirm the deletion. The mapping is removed from your Stedi account.
## Define source and target JSON Schema
You must define a source and a target [JSON Schema](https://json-schema.org/). The source schema describes your incoming data. The target schema describes the shape of the Mappings API output.
For example, if you need to transform [Guide JSON](/edi-platform/operate/transform-json/guide-json) into a custom format for your internal systems, then the [Guide JSON](/edi-platform/operate/transform-json/guide-json) is the source, and the payload your software understands is the target.
You can define the source and target JSON Schemas by doing one of the following:
* [Connect a Stedi event](#connect-a-stedi-event) as the source schema. You must do this when creating a mapping to use with a destination webhook.
* [Connect a stedi guide](#connect-a-stedi-guide) to your mapping. We recommend this approach when you are using mappings with to read or write EDI data according to partner-specific requirements.
* Add a [JSON example file](#add-a-json-example-file).
* Provide a [JSON Schema](#provide-a-json-schema) adhering to [version 2020-12](https://json-schema.org/specification.html) that describes the shape of your data.
### Connect a Stedi event
Destinations are a legacy feature and have been superseded by
[Webhooks](/edi-platform/configure/webhooks). Please [contact
support](https://www.stedi.com/contact) with questions or for help migrating.
You can attach a mapping to a [destination webhook](/edi-platform/configure/destinations/configure-destinations#transform-data-with-mappings) event binding. Stedi uses the mapping to transform the JSON data payload into the required shape before sending it to the configured destination.
You must choose **Event** as the source type when creating a mapping to use with a destination webhook.
If you choose the `transaction.processed.v2` or `fragment.processed.v2` event types, you must also select a Stedi guide to connect to the mapping. Once you've connected your guide, mappings generates the source schema based on the event type you chose and the connected guide.
### Connect a Stedi guide
You can generate the **Source** or **Target** schema from a [Stedi guide](/edi-platform/guides). After you connect a guide, the mappings UI autogenerates the schema and sample JSON document with fields from the guide.
#### Requirements
You must have at least one Stedi guide in your account. You can manually create a guide from PDF EDI specifications or import a pre-made guide from the [Stedi Network](https://www.stedi.com/edi/network).
#### Connect a guide to the mapping
You can connect a guide to both the mapping’s **Source** and **Target** schema. To connect a guide:
1. Navigate to your mapping and edit either the **Source** or the **Target** document.
2. Go to the **Guide** tab to view a list of guides in your Stedi account.
3. Click **Connect** next to the guide you want to use.
Once you've connected your guide, mappings generates the schema and example document based on the guide. The **Schema** and **Example** tabs will become read-only. Refer to [Pull changes from a guide][pull-changes-from-a-guide] on updating the document data based on a guide. To change the schema or example, you must first disconnect the guide – refer to [Disconnect a guide][disconnect-a-guide].
#### Use fragments
If the guide is set up to use [Fragments](/edi-platform/fragments), Stedi updates your options:
* **Inbound fragments:** You can choose whether to create a mapping for the `transaction.processed.v2` event type or the `fragment.processed.v2` event type. Visit [Inbound Fragments](/edi-platform/fragments/inbound-fragments) for details.
* **Outbound fragments:** You can choose whether to create a mapping for the full transaction (no fragments), the fragment wrapper, or the fragment shape. Typically for outbound fragments you need to create two mappings: one mapping for the fragment shape to use with the [Stage Fragment](/api-reference/edi-platform/core/post-fragments) endpoint and one mapping for the fragment wrapper to use with the [Create Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint. Visit [Outbound Fragments](/edi-platform/fragments/outbound-fragments) for details.
#### Pull changes from a guide
Pulling the changes from a guide allows you to update the schema with the latest published changes made to a guide.
To pull changes from a guide:
1. Navigate to your mapping and edit the **Source** or the **Target** document.
2. Go to the **Guide** tab to view the status of the connected guide.
3. Click **Edit** for a document that connects with a guide.
4. Click **Pull changes**. For **Target** schemas, the mappings UI alerts you when guide changes affect existing expressions in the mapping.
5. If there are breaking changes, review them and decide whether you want to continue with the update.
#### Disconnect a guide
Disconnecting a guide preserves the current **Source** and **Target** schemas. Still, you will no longer be able to automatically update them based on the published changes to a guide. You can re-connect a guide at any time if needed.
To disconnect a guide from a mapping document:
1. Edit the **Source** or **Target** and go to the **Guide** tab.
2. Click **Disconnect** and **Confirm**.
### Add a JSON example file
When you add a JSON example file, the Mappings builder autogenerates the JSON Schema based on the example structure.
If you edit the JSON example file, the Mappings builder validates the changes against the existing JSON Schema. If the JSON document does not conform to the JSON Schema, you can either regenerate JSON Schema or update it manually.
> JSON Schema regeneration might remove fields you defined in the JSON Schema
> and did not add to the example file.
### Provide a JSON Schema
When you add a JSON Schema, the Mappings builder autogenerates an example JSON file based on the schema.
Your JSON Schema must define a `default` property that contains an example of data that adheres to the schema. Refer to the JSON documentation for more about [the `default` keyword](https://json-schema.org/understanding-json-schema/reference/annotations).
When you upload a JSON Schema as either the source or target, Mappings builder uses the schema's `default` property to produce the mapping output. If the contents of the `default` property do not conform to the JSON Schema, you can manually amend the contents of the `default` property, amend the JSON Schema itself, or regenerate it automatically.
## Choose target keys
You can choose whether you want to include all or a subset of the incoming JSON fields in the output JSON file. By default, the Mappings builder uses all incoming target keys.
If you only need a subset of the fields that are in the sample select **Target keys**, to change which keys are included.
## Choose a mapping type
The mapping type specifies how the Mappings API generates the output field when the mapping expression doesn't produce a value.
You can select a mapping type from the dropdown menu in the **Output** section. You can choose between:
* Only mapped
* Merge with target
* Pass through
Refer to [Mapping Definition Overview](/edi-platform/mappings/manage-mappings/mapping-definition#mapping-types) for full details about each type and examples of how Mappings generates outputs based on your selection.
## Write mapping expressions
You must map each target key from the source JSON data to a property in the target JSON data. For example, you might map a `product ID` property from the source JSON to a `product number` property in the target JSON.
You do not need to do a one-to-one mapping of incoming properties to outgoing properties. You can create advanced expressions to map text properties to numbers, perform calculations, and more.
You can also use `omitField` to [exclude entire objects](/edi-platform/mappings/jsonata/common-mapping-expressions#conditionally-omitting-objects) or [exclude fields](/edi-platform/mappings/jsonata/common-mapping-expressions#omitting-output-fields) from the output based on a condition. For example, you might only want your output to include the input field `totalPrice` when the number of products is larger than 0.
Visit [Common Mapping Expressions](/edi-platform/mappings/jsonata/common-mapping-expressions) for details and examples for common mapping use cases.
### Handling floating-point arithmetic
It is not recommended to use JSONata for floating point arithmetic, such as
financial calculations. Floating-point arithmetic can introduce rounding
errors, which can accumulate and lead to incorrect results. Visit our [JSONata
Playground](https://stedi.link/UKXfsxe) for an example. We recommend
representing monetary values as integers (e.g. cents) and performing
calculations on those integers.
Instead of JSONata, we recommend representing monetary values as integers (e.g. cents) and performing calculations on those integers.
## Export and import mappings
You can export an existing mapping and import it into another Stedi account.
To export a mapping, navigate to the [Mappings dashboard][mappings-product], click the ellipses (`...`) for the Mapping you want to export, and click **Export**. A .zip archive of the mapping data is downloaded to your machine.
To import a mapping .zip archive into a Stedi account: 1. Sign into the account and go to [Mappings dashboard][mappings-product]. 1. Click **Import**. 1. Either click **Upload** to choose a .zip archive from your machine or drag and drop the .zip archive onto the page. 1. Choose a **Mapping name** and click **Proceed with import**. The new mapping is now available in the Stedi account.
## Duplicate and version mappings
You may want to duplicate a mapping to create an updated version or to use an existing mapping as a starting point for a new one.
Duplicated mappings have a unique ID from the original that you can use in [Mappings API](/edi-platform/mappings/manage-mappings/api-guide) calls. This approach lets you quickly roll back to the previous version if necessary.
To duplicate a mapping:
1. Go to your [Mappings dashboard][mappings-product], click the ellipses (`...`) next to the mapping you want to duplicate, and select **Duplicate**.
2. Choose a name for the duplicated mapping and click **Duplicate**. The duplicated mapping is now available in your Stedi account.
# Customize the ISA and GS headers
Source: https://www.stedi.com/docs/edi-platform/operate/generate-edi/envelope-overrides
***
title: Customize the ISA and GS headers
sidebarTitle: "Customize the envelope"
--------------------------------------
You can customize an EDI file's Interchange (`ISA`) and Group (`GS`) headers - also known as the envelope - using the [Create Outbound Interchange](/api-reference/edi-platform/post-generate-edi) endpoint.
If you don't need to customize the envelope, we strongly recommend generating
EDI files with the [Create Outbound
Transaction](/edi-platform/operate/generate-edi) endpoint instead because it
is simpler and easier to use.
## Interchange overrides
You can customize the following elements in the `ISA` header:
* **Interchange Authorization values** (`ISA01` to `ISA04`): Some trading partners require additional information in these elements to verify the transaction.
* **Interchange Version Control Number Code** (`ISA12`): Stedi defaults to using the X12 release number of the guide associated with the transaction. However, some partners require a different release for the `ISA` envelope.
* **Acknowledgment Requested Code** (`ISA14`): This code indicates whether you are requesting a `TA1` Interchange Acknowledgments.
* **Interchange Usage Indicator Code** (`ISA15`): This code indicates whether data is test, production, or information. Stedi defaults to `P` for production data, but you may need to set this to `T` when sending test data.
Visit the [Create Outbound Transaction](/api-reference/edi-platform/post-transactions) documentation for more details.
```shell
curl --location 'https://core.us.stedi.com/2023-08-01/x12/partnerships//generate-edi' \
--header 'Content-Type: application/json' --header "Authorization: ${STEDI_API_KEY}" \
--data-raw '{
"filename": "my-output-file.edi",
"overrides": {
"acknowledgmentRequestedCode": "1",
"interchangeUsageIndicator": "T",
"interchangeControlVersionNumberCode": "00200"
},
"transactionGroups": [
{
"transactionSettingId": "",
"transactions": [
{
"heading": {},
"detail": {},
"summary": {}
}
]
}
]
}'
```
```json
{
"edi": "ISA*00* *00* *ZZ*THISISME *14*ANOTHERMERCH *230628*1159*U*00200*000000024*1*T*>~GS*PO*MINE*MYAPPID*20230628*115907*000000024*X*005010~ST*850*0001~BEG*00*DS*365465413**20220830~REF*CO*ACME-4567~REF*ZZ*Thank you for your business~PER*OC*Marvin Acme*TE*973-555-1212*EM*marvin@acme.com~TD5****ZZ*FHD~N1*ST*Wile E Coyote*92*123~N3*111 Canyon Court~N4*Phoenix*AZ*85001*US~PO1*item-1*0008*EA*400**VC*VND1234567*SK*ACM/8900-400~PID*F****400 pound anvil~PO1*item-2*0004*EA*125**VC*VND000111222*SK*ACM/1100-001~PID*F****Detonator~CTT*2~AMT*TT*3700~SE*16*0001~GE*1*000000024~IEA*1*000000024~",
"artifactId": "my-output-file.edi",
"fileExecutionId": "b70199fa-4a11-4610-861e-aa7fff4ae09b"
}
```
## Group overrides
By default, Stedi generates EDI files using the application IDs (`GS-02` and `GS-03` elements) configured for each profile within the partnership. However, some partners use multiple application IDs to route files to different locations.
To set custom application IDs, set the `localApplicationId` and the `partnerApplicationId` properties in the `override` object. These values are optional; you should only send them when you need to override the application IDs configured within each profile.
You can include multiple `overrides` objects to customize the application IDs for each transaction group in the file.
```shell
curl --location 'https://core.us.stedi.com/2023-08-01/x12/partnerships//generate-edi' \
--header 'Content-Type: application/json' --header "Authorization: ${STEDI_API_KEY}" \
--data-raw '{
"filename": "my-output-file.edi",
"transactionGroups": [
{
"transactionSettingId": "",
"overrides": {
"localApplicationId": "LOC1",
"partnerApplicationId": "PART1"
},
"transactions": [
{
"heading": {},
"detail": {},
"summary": {}
}
]
},
{
"transactionSettingId": "",
"overrides": {
"localApplicationId": "LOC2",
"partnerApplicationId": "PART2"
},
"transactions": [
{
"heading": {},
"detail": {},
"summary": {}
}
]
}
]
}'
```
```json
{
"edi": "ISA*00* *00* *ZZ*THISISME *14*ANOTHERMERCH *230628*1159*U*00501*000000024*1*T*>~GS*PO*LOC*PART*20230628*115907*000000024*X*005010~ST*850*0001~BEG*00*DS*365465413**20220830~REF*CO*ACME-4567~REF*ZZ*Thank you for your business~PER*OC*Marvin Acme*TE*973-555-1212*EM*marvin@acme.com~TD5****ZZ*FHD~N1*ST*Wile E Coyote*92*123~N3*111 Canyon Court~N4*Phoenix*AZ*85001*US~PO1*item-1*0008*EA*400**VC*VND1234567*SK*ACM/8900-400~PID*F****400 pound anvil~PO1*item-2*0004*EA*125**VC*VND000111222*SK*ACM/1100-001~PID*F****Detonator~CTT*2~AMT*TT*3700~SE*16*0001~GE*1*000000024~IEA*1*000000024~",
"artifactId": "my-output-file.edi",
"fileExecutionId": "b70199fa-4a11-4610-861e-aa7fff4ae09b"
}
```
## Call the Interchange API
The [Create Outbound Interchange](/api-reference/edi-platform/post-generate-edi) endpoint can generate fully-formed EDI files containing multiple transactions and even multiple transaction types.
### Request data
The API uses the following data to generate and deliver an EDI file.
| Data | Required | Description |
| ---------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `partnershipId` | Yes | Include this ID within the API route to identify the associated partnership. You can find this ID on the [Trading partners](https://portal.stedi.com/app/core/partnerships) page under **Partnership identifier**. |
| `transactionGroups` | Yes | The Generate API accepts multiple arrays of transactions in a single API call, allowing you to send multiple transactions or even multiple functional groups in a single file. If you only plan to send a single type of transaction (such as a Purchase Order), then your API request should have one transaction group. |
| `transactionGroups.transactionSettingId` | Yes | This ID specifies the outbound transaction setting Stedi should use to validate the transaction data and generate the file. To find this ID, go to the partnership, find the outbound transaction setting, and copy its **Transaction Setting ID**. |
| `transactionGroups.transactions` | Yes | This object contains the transaction data. It must conform to the [Guide JSON format](/edi-platform/operate/transform-json/guide-json) for the specified transaction setting. |
| `filename` | | Specify the name of the generated EDI file. Stedi overwrites files with the same name, so we recommend making the filename unique by including a timestamp or other identifier. If you do not specify a filename, Stedi autogenerates a unique name using a UUID. |
| Envelope overrides | | You can use several optional parameters to customize aspects of the EDI envelope - both the [`ISA` header](#interchange-overrides) and [`GS` header](#group-overrides). |
### Sample request and response
The following example shows a cURL request and response.
The API returns the full X12 EDI file in the response. The response also includes an `artifactId` (equivalent to the file name) and a globally unique `fileExecutionId` that you can use to locate the generated file.
```shell
curl --request POST \
--url https://core.us.stedi.com/2023-08-01/x12/partnerships/{partnershipId}/generate-edi \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"filename": "",
"transactionGroups": [
{
"transactionSettingId": "",
"transactions": [
{
"heading": {},
"detail": {}
}
]
}
]
}'
```
```shell
curl --request POST \
--url https://core.us.stedi.com/2023-08-01/x12/partnerships/{partnershipId}/generate-edi \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"filename": "test-interchange.edi",
"transactionGroups": [
{
"transactionSettingId": "005010X220A1-834",
"transactions": [
{
"heading": {
"transaction_set_header_ST": {
"transaction_set_identifier_code_01": "834",
"transaction_set_control_number_02": 12345,
"implementation_convention_reference_03": "005010X220A1"
},
"beginning_segment_BGN": {
"transaction_set_purpose_code_01": "00",
"transaction_set_reference_number_02": "12456",
"transaction_set_creation_date_03": "2002-06-01",
"transaction_set_creation_time_04": "12:00",
"action_code_08": "2"
},
"transaction_set_policy_number_REF": {
"reference_identification_qualifier_01": "38",
"master_policy_number_02": "ABCD012354"
},
"sponsor_name_N1_loop": {
"sponsor_name_N1": {
"entity_identifier_code_01": "P5",
"identification_code_qualifier_03": "FI",
"sponsor_identifier_04": "999888777"
}
},
"payer_N1_loop": {
"payer_N1": {
"entity_identifier_code_01": "IN",
"identification_code_qualifier_03": "FI",
"insurer_identification_code_04": "654456654"
}
}
},
"detail": {
"member_level_detail_INS_loop": [
{
"member_level_detail_INS": {
"member_indicator_01": "Y",
"individual_relationship_code_02": "18",
"maintenance_type_code_03": "025",
"benefit_status_code_05": "A",
"employment_status_code_08": "FT"
},
"subscriber_identifier_REF": {
"reference_identification_qualifier_01": "0F",
"subscriber_identifier_02": "202443307"
},
"member_policy_number_REF": {
"reference_identification_qualifier_01": "1L",
"member_group_or_policy_number_02": "123456001"
},
"member_name_NM1_loop": {
"member_name_NM1": {
"entity_identifier_code_01": "IL",
"entity_type_qualifier_02": "1",
"member_last_name_03": "SMITH",
"member_first_name_04": "WILLIAM",
"identification_code_qualifier_08": "ZZ",
"member_identifier_09": "202443307"
}
}
}
]
}
}
]
}
]
}'
```
```json
{
"edi": "ISA*00* *00* *ZZ*LOCAL *ZZ*TEST *250519*2310*^*00501*000000002*0*P*>~GS*BE*LOCAL*TEST*20250519*231001*2*X*005010X220A1~ST*834*12345*005010X220A1~BGN*00*12456*20020601*1200****2~REF*38*ABCD012354~N1*P5**FI*999888777~N1*IN**FI*654456654~INS*Y*18*025**A***FT~REF*0F*202443307~REF*1L*123456001~NM1*IL*1*SMITH*WILLIAM****ZZ*202443307~SE*10*12345~GE*1*2~IEA*1*000000002~",
"artifactId": "test-interchange.edi",
"fileExecutionId": "f47a0697-d06c-47f0-a5a5-fa79994f3ce0"
}
```
# Create outbound transaction
Source: https://www.stedi.com/docs/edi-platform/operate/generate-edi
***
title: Create outbound transaction
sidebarTitle: "Create outbound transaction"
-------------------------------------------
Generate and deliver fully-formed EDI files to your trading partners with the [Create Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint.
This is the simplest way to send EDI files with Stedi.

## Format transaction data
Unless you’re using [mappings](/edi-platform/mappings), you must submit transaction data to the API in [Guide JSON](/edi-platform/operate/transform-json/guide-json), a format that matches the JSON Schema of the guide associated with the outbound transaction setting.
### Guide JSON schema
To find the JSON Schema for a transaction:
1. Navigate to the [Trading partners page](https://portal.stedi.com/app/core/partnerships).
2. Select the partnership.
3. Click the name of the guide associated with the outbound transaction setting.
4. Open the **Actions** menu and select **View schema**.
5. This is the JSON Schema you must use when sending transaction data to the API. You must include every segment and element marked as required in the guide.
You can also use the [send outbound test files](/edi-platform/operate/generate-test-files) feature to generate a sample JSON payload that matches your guide's JSON Schema. You can then edit the sample payload as needed.
### Mapping ID and schema
You can optionally specify a mapping to transform transaction data from your system into Guide JSON format. In this case, you must send data to the API in the mapping’s source JSON Schema.
To find the mapping ID and schema:
1. Go to the [Mappings page](https://portal.stedi.com/app/mappings) and copy the ID field for the mapping you want to use.
2. Click the mapping’s name to view its details.
3. Click **Test mapping**. The test input JSON shape is the shape you must use when sending transaction data to the API.
## Call the API
When you call the Create Outbound Transaction endpoint, Stedi:
1. Applies the mapping (if present) to the provided transaction data.
2. Adds [fragments](/edi-platform/fragments) from specified fragment groups (if present).
3. Generates an EDI file according to the Stedi guide attached to the [outbound transaction setting](/edi-platform/configure/trading-partners/transaction-settings#create-transaction-settings). This includes adding required envelope information (`ISA` and `GS` headers) and autogenerated control numbers.
4. Delivers the EDI file to your trading partner through the [connection](/edi-platform/configure/trading-partners/connections) specified in the outbound transaction setting.
### Create request
The API uses the following data to generate and deliver an EDI file.
| Data | Required | Description |
| ---------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API key | Yes | You must pass a Stedi API key in the `Authorization` header of every request. You can [create an API key](/api-reference#authentication) in the Stedi portal. |
| `partnershipId` | Yes | Include this ID in the API route to identify the associated partnership. You can find this ID on the [Trading partners](https://portal.stedi.com/app/core/partnerships) page under **Partnership identifier**. |
| `transactionSettingId` | Yes | Include this ID in the API route to identify the outbound transaction setting Stedi should use to validate the transaction data and generate the file. To find this ID, go to the partnership, find the outbound transaction setting, and copy its **Transaction Setting ID**. |
| `transaction` | Yes | This payload contains the transaction data. Without a mapping, this transaction data must be \< 5MB and the shape must match the Guide JSON format for the specified outbound transaction setting. With a mapping, this transaction data must be \< 4MB and the shape must match the mapping's source schema. |
| `filename` | | Specify the name of the generated EDI file. Stedi overwrites files with the same name, so we recommend making the filename unique by including a timestamp or other identifier. The filename you specify here takes precedence over the **Filename expression** (if present) set on the outbound transaction setting. If you do not specify a filename, and there isn't one set on the outbound transaction setting, Stedi autogenerates a unique name using a UUID. |
| `fragmentGroupIds` | | Specify which fragments Stedi should insert into the transaction. Visit [outbound fragments](/edi-platform/fragments/outbound-fragments) for details. |
| `mappingId` | | Specify the mapping Stedi should use to transform the transaction data to Guide JSON format. |
### Sample request and response
The following example shows a cURL request and response.
The API returns a globally unique `fileExecutionId` that you can use to locate the generated file.
```shell
curl --request POST \
--url https://core.us.stedi.com/2023-08-01/partnerships/{partnershipId}/transactions/{transactionSettingId} \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"filename": "my-output-file.edi",
"transaction": {
{
"heading": {},
"detail": {}
}
}
}'
```
```shell
curl --request POST \
--url https://core.us.stedi.com/2023-08-01/partnerships/{partnershipId}/transactions/{transactionSettingId} \
--header 'Authorization: ' \
--header 'Content-Type: application/json' \
--data '{
"filename": "my-output-file.edi",
"transaction": {
"heading": {
"transaction_set_header_ST": {
"transaction_set_identifier_code_01": "834",
"transaction_set_control_number_02": 12345,
"implementation_convention_reference_03": "005010X220A1"
},
"beginning_segment_BGN": {
"transaction_set_purpose_code_01": "00",
"transaction_set_reference_number_02": "12456",
"transaction_set_creation_date_03": "2002-06-01",
"transaction_set_creation_time_04": "12:00",
"action_code_08": "2"
},
"transaction_set_policy_number_REF": {
"reference_identification_qualifier_01": "38",
"master_policy_number_02": "ABCD012354"
},
"sponsor_name_N1_loop": {
"sponsor_name_N1": {
"entity_identifier_code_01": "P5",
"identification_code_qualifier_03": "FI",
"sponsor_identifier_04": "999888777"
}
},
"payer_N1_loop": {
"payer_N1": {
"entity_identifier_code_01": "IN",
"identification_code_qualifier_03": "FI",
"insurer_identification_code_04": "654456654"
}
}
},
"detail": {
"member_level_detail_INS_loop": [
{
"member_level_detail_INS": {
"member_indicator_01": "Y",
"individual_relationship_code_02": "18",
"maintenance_type_code_03": "025",
"benefit_status_code_05": "A",
"employment_status_code_08": "FT"
},
"subscriber_identifier_REF": {
"reference_identification_qualifier_01": "0F",
"subscriber_identifier_02": "202443307"
},
"member_policy_number_REF": {
"reference_identification_qualifier_01": "1L",
"member_group_or_policy_number_02": "123456001"
},
"member_name_NM1_loop": {
"member_name_NM1": {
"entity_identifier_code_01": "IL",
"entity_type_qualifier_02": "1",
"member_last_name_03": "SMITH",
"member_first_name_04": "WILLIAM",
"identification_code_qualifier_08": "ZZ",
"member_identifier_09": "202443307"
}
}
}
]
}
}
}'
```
```json
{ "fileExecutionId": "74cd4ad2-5a7c-47d7-9477-6829abcee6ad" }
```
## Acknowledgments
Stedi can automatically generate 997 or 999 acknowledgments for every inbound transaction associated with a partnership, so you should not need to use the API to send 997s or 999s. Visit [Acknowledgments](/edi-platform/configure/trading-partners/functional-acknowledgments) for details on enabling this functionality.
## Timezone and time format
Stedi uses the following default values:
* **Timezone:** UTC | Used in the `ISA` and `GS` segments
* **Time format:** `HHMMSS` | The [GS-05](https://www.stedi.com/edi/x12/segment/GS#GS-05) time element
You can change these values in the partnership's **Advanced settings** menu.
## Character sets
By default, Stedi doesn't enforce any character restrictions for outbound files. As long as the payload is valid JSON that meets the guide's JSON Schema, Stedi can generate an EDI file and deliver it to your trading partner.
However, some trading partners may have restrictions on the characters they can accept. For example, certain partners may only accept a subset of characters called the Basic Character Set, which doesn't include lowercase or special characters. Others may accept the Extended Character Set, which has a more expansive set of character options. Others in the healthcare industry may use the HIPAA Extended Character Set, which is a subset of the Extended Character Set (note that HIPAA guidelines require the use of either the Basic or HIPAA Extended character set for HIPAA transactions).
### Restrict characters in outbound files
You can select a character set to use when generating outbound files in the partnership's **Advanced settings** menu.
Once you select a character set, Stedi rejects EDI generation requests that contain characters outside of the specified set. For example, if you select the **Basic** character set, Stedi rejects requests that contain lowercase letters and other unsupported characters.
There are three character set options.
#### Basic Character Set
Includes uppercase letters, digits, space, and some special characters. Lowercase letters and special language characters like `ñ` are not included.
In order to be compliant with X12 HIPAA guidelines, all trading partners must support the Basic Character Set at a minimum.
The following special characters are included:

#### HIPAA Extended Character Set
Includes the characters listed in Basic, plus lowercase letters and additional special characters, such as `@` and `#`.
X12 HIPAA guidelines state the following:
> In the absence of a specific trading partner agreement to the contrary, trading partners will assume that the \[HIPAA] extended character set is acceptable.
The following additional special characters are included:

#### Standard Extended Character Set
Includes the characters in HIPAA Extended, plus select additional language characters, such as `ñ`. The standard Extended Character Set is the most common character set outside of healthcare (for example, in retail and logistics).
According to HIPAA guidelines, the Standard Extended character set is not allowed in HIPAA-compliant transactions (see X12 RFI [2212](https://x12.org/resources/requests-for-interpretation/rfi-2212-language-characters-837)).
The following additional language characters are included:

### Character set questionnaire
You can send the [X12 Character Set questionnaire](https://docs.google.com/document/d/1oQBLskIvfhMBdze77YjUrfHw_htV_2ZzhdHBqoGWBLU/edit) to your trading partners to determine which characters they support, and thus which character set you should use when generating outbound files.
## Custom filenames
You can specify a custom filename for the generated EDI file either in the [outbound transaction setting](/edi-platform/configure/trading-partners/transaction-settings#outbound-custom-filename-expression) or with the `filename` field in your API request. If you don't specify a filename, Stedi autogenerates one using a UUID.
## Payload limits
Without a mapping, the Create Outbound Transaction endpoint accepts payloads up to 5MB. With a mapping, the payload must be \< 4MB. You can use [outbound fragments](/edi-platform/fragments/outbound-fragments) to split larger transactions into smaller chunks before sending them to the API.
If this presents issues for your integration, please [let us know](https://www.stedi.com/contact), and we can help develop a solution.
# Guide JSON format
Source: https://www.stedi.com/docs/edi-platform/operate/transform-json/guide-json
***
title: Guide JSON format
sidebartitle: 'Guide JSON format'
---------------------------------
Stedi's native format for EDI transactions is called Guide JSON. It closely reflects the structure of an EDI transaction, but uses JSON instead of EDI syntax.
* When you [Generate EDI](/edi-platform/operate/generate-edi), Stedi accepts Guide JSON as input, and delivers a fully-validated EDI file to your partner.
* Stedi [parses inbound EDI](/edi-platform/operate/parse-edi) into Guide JSON format.
## Example
The following example shows an 834 benefit enrollment in X12 EDI and Guide JSON formats. The EDI format is in the first tab, and the Guide JSON is in the second tab.
```shell tab="834 benefit enrollment EDI"
ISA*00* *00* *ZZ*SENDERNAME *ZZ*RECEIVERNAME *041227*1324*^*00501*000000103*0*P*>~
GS*BE*SENDERNAME*RECEIVERNAME*20041227*1324*000000103*X*005010X220A1~
ST*834*12345*005010X220A1~
BGN*00*12456*19980520*1200****2~
REF*38*ABCD012354~
N1*P5**FI*999888777~
N1*IN**FI*654456654~
INS*N*19*024*07*A~
REF*0F*123456789~
REF*1L*123456001~
DTP*357*D8*19960801~
NM1*IL*1*DOE*JAMES*E***34*103229876~
DMG*D8*19770816*M~
SE*12*12345~
GE*1*000000103~
IEA*1*000000103~
```
```json tab="834 benefit enrollment JSON"
{
"heading": {
"transaction_set_header_ST": {
"transaction_set_identifier_code_01": "834",
"transaction_set_control_number_02": 12345,
"implementation_convention_reference_03": "005010X220A1"
},
"beginning_segment_BGN": {
"transaction_set_purpose_code_01": "00",
"transaction_set_reference_number_02": "12456",
"transaction_set_creation_date_03": "1998-05-20",
"transaction_set_creation_time_04": "12:00",
"action_code_08": "2"
},
"transaction_set_policy_number_REF": {
"reference_identification_qualifier_01": "38",
"master_policy_number_02": "ABCD012354"
},
"sponsor_name_N1_loop": {
"sponsor_name_N1": {
"entity_identifier_code_01": "P5",
"identification_code_qualifier_03": "FI",
"sponsor_identifier_04": "999888777"
}
},
"payer_N1_loop": {
"payer_N1": {
"entity_identifier_code_01": "IN",
"identification_code_qualifier_03": "FI",
"insurer_identification_code_04": "654456654"
}
}
},
"detail": {
"member_level_detail_INS_loop": [
{
"member_level_detail_INS": {
"member_indicator_01": "N",
"individual_relationship_code_02": "19",
"maintenance_type_code_03": "024",
"maintenance_reason_code_04": "07",
"benefit_status_code_05": "A"
},
"subscriber_identifier_REF": {
"reference_identification_qualifier_01": "0F",
"subscriber_identifier_02": "123456789"
},
"member_policy_number_REF": {
"reference_identification_qualifier_01": "1L",
"member_group_or_policy_number_02": "123456001"
},
"member_level_dates_DTP": [
{
"date_time_qualifier_01": "357",
"date_time_period_format_qualifier_02": "D8",
"status_information_effective_date_03": "19960801"
}
],
"member_name_NM1_loop": {
"member_name_NM1": {
"entity_identifier_code_01": "IL",
"entity_type_qualifier_02": "1",
"member_last_name_03": "DOE",
"member_first_name_04": "JAMES",
"member_middle_name_05": "E",
"identification_code_qualifier_08": "34",
"member_identifier_09": "103229876"
},
"member_demographics_DMG": {
"date_time_period_format_qualifier_01": "D8",
"member_birth_date_02": "19770816",
"gender_code_03": "M"
}
}
}
],
"transaction_set_trailer_SE": {
"transaction_segment_count_01": 12,
"transaction_set_control_number_02": 12345
}
}
}
```
## What is Guide JSON?
Guides are Stedi's machine-readable representation of the EDI specifications that your trading partners provide to you (typically in the form of PDF, Excel, or Word files), or that you provide to your trading partners. You can view and import guides from [X12 HIPAA transactions](https://www.stedi.com/edi/network/hipaa) and [popular logistics and retail trading partners](https://www.stedi.com/edi/network) as needed for your integration.
Each guide is backed by a JSON Schema that defines the structure of the EDI transaction. **Guide JSON** is JSON data that conforms to the **guide's** schema.
### How Stedi uses Guide JSON
* **Inbound files:** Stedi uses the inbound [transaction settings](/edi-platform/configure/trading-partners/transaction-settings) within the partnership to determine which Stedi guide to use for validation and translation. If validation is successful, Stedi parses the file into one or more transactions, and outputs them in Guide JSON.
* **Outbound files:** You supply Stedi's [Generate Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint with transaction data in the Guide JSON format. Stedi uses that data to generate an EDI file and deliver it to your trading partner.
### Find a guide's JSON Schema
To find the JSON Schema for a guide:
1. Navigate to the [Guides](https://portal.stedi.com/app/guides) page in your Stedi account.
2. Click the guide you want to view.
3. Open the **Actions** menu and select **View schema**.
## How Guide JSON formats vary
Guide JSON formats vary in three ways. You must account for these differences when you receive Guide JSON webhooks for inbound transactions, and when you call Stedi APIs to send outbound transactions.
### Transaction type
Since a guide can represent any of the 300+ EDI transaction types, the Guide JSON (and corresponding JSON Schema) will differ depending on the transaction type. For example, the Guide JSON for an 834 benefit enrollment will differ from the Guide JSON for an 835 Claim Payment/Advice (also known as an ERA). This means that the payloads you receive from Stedi through webhooks will vary depending on the transaction type, and the payloads you send to Stedi APIs will also vary depending on the transaction type.
### Release
X12 has 30+ releases, or versions. There are often breaking changes between X12 releases, which makes it impossible to reliably canonicalize transactions across releases. Since different trading partners use different releases, the Guide JSON you have to accept from and provide to Stedi differ depending on the release. For example, the Guide JSON for an 850 Purchase Order in X12 release `004010` will be different than the Guide JSON for an 850 Purchase Order in X12 release `005010`.
### Trading partner
Since different trading partners use different EDI specifications, the Guide JSON may differ depending on the trading partner. For example, the [Amazon Retail 855 PO Acknowledgment](https://portal.stedi.com/app/guides/view/amazon/retail-purchase-order-acknowledgment/01H25HYSGSFKB0P1G99H31K9YP#properties.detail.properties.baseline_item_data_PO1_loop.items.properties.pricing_information_CTP) allows you to optionally specify pricing information in the `CTP` segment, but the [Walmart 855](https://portal.stedi.com/app/guides/view/walmart-edi/purchase-order-acknowledgment/01GNZA51CHFJJD9Y75GSSCXHHW#properties.detail.properties.baseline_item_data_PO1_loop.items.properties.baseline_item_data_PO1) does not.
These differences don't apply to X12 HIPAA transactions, which are standardized across trading partners. For example, the Guide JSON for an 834 benefit enrollment will be the same regardless of which payer you send it to.
# Choose a transformation approach
Source: https://www.stedi.com/docs/edi-platform/operate/transform-json/transformation-approaches
***
title: Choose a transformation approach
sidebarTitle: "Transformation approaches"
-----------------------------------------
Stedi supports three ways to transform transaction data to and from [Guide JSON](/edi-platform/operate/transform-json/guide-json) format: Stedi Mappings, writing custom code, and using an iPaaS platform.
The approach you choose depends on your circumstances and preferences.
## Stedi Mappings
This functionality is available in a Stedi module. [Contact us](https://www.stedi.com/contact) for details.
[Stedi Mappings](/edi-platform/mappings) is a powerful JSON-to-JSON transformation engine. You can build mappings using Stedi's visual mapper and use mappings to transform data for both inbound and outbound transactions.
* **Inbound transactions**: Configure [webhooks](/edi-platform/configure/webhooks) to send `transaction.processed.v2` events to your API. Then use the [Map Transaction Output](/api-reference/edi-platform/get-map-transaction-output) endpoint to return the mapped output of the processed inbound transaction.
* **Outbound transactions**: Call the [Create Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint with a mapping ID. Stedi uses the specified mapping to automatically transform your system's data into Guide JSON before generating and delivering the EDI file.
### When to use
We recommend using Stedi Mappings when:
* Your system can natively produce and consume JSON payloads. Mappings is designed to map one JSON shape to another JSON shape. If your system uses another format like XML or CSV, Mappings isn't a fit.
* You plan to do one-step transformations without multi-step processing. For example, you need to reshape a Guide JSON payload to post to a simple API endpoint.
* You want your business or operations team to manage mappings. The first few mappings typically require an engineer and often some pairing help from Stedi's Customer Success team. Once you build a few examples, business users can often edit, maintain, and build mappings independently.
* You want a solution that's integrated with the Stedi platform. Stedi's Mappings product is integrated with Stedi Guides, making it easier to build mappings from any Guide JSON Schema and test mappings using sample Guide JSON payloads. You can also control which users can view, edit, and deploy mappings with [Role-Based Access Control (RBAC)](/accounts-and-billing#assigning-member-roles).
### Cons
We don't recommend using Mappings alone to build the end-to-end functionality for use cases requiring dynamic lookups or multi-step processing.
In many integrations, you need to translate Guide JSON into your system's API shape and then dynamically look up internal IDs from a constantly-changing list. For example, you might need to call out to an ERP or API to look up a customer's ID and use that information to replace values in the JSON object before posting to an API.
To accomplish this flow, you would need to first transform the Guide JSON into your system's API shape using Mappings and then use your own codebase or iPaaS platform to perform the lookups and replace the values. This is a viable option, but the approach requires maintaining the transformation steps in two separate systems – the field mappings in Stedi's Mapping product, and the dynamic lookups in custom code or an iPaaS platform. If you prefer to keep all of your logic in one place, you can do all of the transformations in your own codebase or an iPaaS platform, without using Stedi Mappings.
## Custom code
You receive transaction data from Stedi in [Guide JSON](/edi-platform/operate/transform-json/guide-json) format.
You write the required logic to transform Guide JSON to your preferred format and
run it on your infrastructure.
* **Inbound transactions**: Retrieve the processed transaction data as-is. Your transformation code will map that payload into your system’s format and deliver it to the ultimate destination.
* **Outbound transactions**: Transform your system’s data into Guide JSON and call the [Create Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint to generate the EDI file and deliver it to your trading partner.
### When to use
We recommend writing custom transformation code when:
* You want to manage data transformations and business logic in your own codebase. For example, you want to write tests and and deploy changes using your existing CI/CD pipeline.
* You only need a small number of mappings that won't change very often. For example, a Revenue Cycle Management (RCM) platform may create a custom mapping to transform Stedi's JSON format for 835 Electronic Remittance Advice (ERA) transactions into the preferred shape for their internal systems.
* You can have engineers involved in every mapping change. Engineers will need to make the changes and ensure that every change is well-tested and deployed in a controlled manner.
* You need to perform complex lookups or multi-step processing. For example, you need to dynamically replace values in the JSON object prior to posting to your API.
### Cons
Coding your own mappings can be cumbersome when you need to build more than a few mappings or your mappings change frequently. For example, a logistics platform may need to support hundreds of different 204 Load Tender formats from different carriers, each with their own mapping.
Generating and maintaining many custom mappings usually requires a lot of coordination between business and engineering teams, which can lead to delays in getting new mappings into production.
## iPaaS platforms
iPaaS platforms like Workato or Tray.io are purpose-built to allow non-engineers to integrate and automate business processes. Just like you can use an iPaaS platform to integrate your ERP or custom system with Salesforce or Shopify, you can use an iPaaS platform to integrate your system with Stedi.
* **Inbound transactions**: Configure [webhooks](/edi-platform/configure/webhooks) to trigger a workflow run once Stedi has successfully processed a transaction. The workflow should transform the Guide JSON into your system’s format and then use a pre-built or custom connector to deliver the transformed payload to your system.
* **Outbound transactions**: You can use the iPaaS platform’s built-in functionality to map your system’s data into Guide JSON, and then use the iPaaS platform’s pre-built HTTP connector to call the [Create Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint with the transformed payload.
### When to use
We recommend using an iPaaS platform when:
* You want to leverage iPaaS functionality. iPaaS platforms offer a wide variety of functionality that is useful for integration scenarios, such as a graphical interface to build integration flows, pre-built connectors, support for API creation and management, data mapping tools, and the ability to orchestrate complex integration scenarios involving multiple endpoints.
* You're already using an off-the-shelf business system (such as a CRM, ERP, or TMS) that is supported by the iPaaS platform.
* You want to build and maintain EDI integrations without involving engineers.
### Cons
* You need a separate subscription to an iPaaS platform, which incurs an additional cost. However, this approach often ultimately reduces costs over time because you don't need engineers to build or maintain your integrations.
* You will need to keep your mapping shape definitions in sync between Stedi and the iPaaS platform. For example, if you update a Stedi Guide to include a new field, you must 1) update any mappings that use the new field and then 2) update the schema in the iPaaS platform. These duplicate updates can be cumbersome and lead to processing errors if not completed in sync.
If your iPaaS platform supports [JSON Schema](https://json-schema.org/), you
can export the Guide JSON Schema from Stedi and import it to your iPaaS
platform. This approach allows you to use the iPaaS platform's built-in data
mapping tools to map your system's data into Guide JSON and will make it
easier to update the schema as it changes.
# Overview - Transform Guide JSON
Source: https://www.stedi.com/docs/edi-platform/operate/transform-json/transforming-data
***
title: Overview - Transform Guide JSON
sidebarTitle: 'Overview'
------------------------
Similar to working with transactions from platforms like Stripe or Shopify, you need
to transform Stedi's [Guide JSON](/edi-platform/operate/transform-json/guide-json) format to and
from a shape that your system can understand.
## Inbound transactions
Stedi parses and translates inbound files from your trading partner into Guide JSON format. You can then choose a [transformation approach](/edi-platform/operate/transform-json/transformation-approaches) to reshape it into your system's format.
## Outbound transactions
For outbound transactions, you need to call the [Generate Outbound Transaction](/api-reference/edi-platform/post-transactions) endpoint with a Guide JSON payload. For example, you may need to translate employee records exported from your internal database into Guide JSON to create an 834 benefit enrollment file.
Prior to calling the API, you can choose a [transformation approach](/edi-platform/operate/transform-json/transformation-approaches) to reshape data from your system into Stedi's Guide JSON format.
# Bucket Connections
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/buckets
***
title: Bucket Connections
sidebarTitle: Buckets
---------------------
Please [contact us](https://www.stedi.com/contact) if you need access to this
feature.
For advanced use cases that other connection types can't cover, Stedi offers bucket connections.
We recommend using other connection types when possible. If you think your use
case requires a bucket connection, reach out to
[support](https://www.stedi.com/contact) for help setting it up.
To create a bucket connection:
1. Select **Bucket** as the **Connection Type**.
2. Enter a descriptive **Connection name**.
3. Select a **root path**. This is the directory in which the inbound and outbound transaction directories will be created. Stedi will automatically suggest a root path based on the partnership ID. You can change this if needed.
4. Choose an inbound directory name that identifies where inbound files should be retrieved for processing.
5. Choose an outbound directory name that identifies where outbound files should be placed when created.
6. Click the **Create connection** to save the connection. You can now associate this connection with one or more [transaction settings](/edi-platform/configure/trading-partners/transaction-settings).
# Choosing a connection type
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/choosing-the-right-connection-type
***
## title: Choosing a connection type
Often, your trading partner will request that you set up a specific type of connection protocol. However, it's important to understand the pros and cons of each approach.
## Connection recommendations
We recommend the following in order of most preferred to least preferred:
1. **[Stedi-run SFTP/FTPS](/edi-platform/configure/trading-partners/connections/stedi-ftp):** This connection type is extremely simple to set up and requires no ongoing maintenance. Outbound files sent to partners using Stedi SFTP are instantly available for partners to pick up. Inbound file processing is event-driven, and Stedi processes files instantly upon receipt. Stedi SFTP scales virtually infinitely. However, most large trading partners are unwilling to connect to external SFTP servers and require that you connect to their server instead.
2. **[Remote SFTP/FTPS](/edi-platform/configure/trading-partners/connections/remote-ftp):** Stedi can also connect to partner or third-party SFTP/FTPS/FTP servers. Stedi delivers outbound files to your trading partners instantly and processes inbound files on a polling schedule. By default, Stedi polls every 5 minutes, but you can set a custom polling interval in the connection's configuration settings.
3. **[AS2](/edi-platform/configure/trading-partners/connections/as2/as2-overview):** For partners that are unable to connect over SFTP, Stedi offers a hosted AS2 option. The AS2 protocol comes with serious drawbacks, so we recommend only using it as a last resort. **If your partner requests AS2 connectivity, we strongly recommend asking if SFTP is an option instead.**
## Problems with AS2
AS2 has several significant drawbacks:
* It is tedious to set up and requires getting complex, unfamiliar configuration settings just right. Debugging AS2 connection issues often involves getting both parties on a call to dive into detailed logs to figure out what is preventing the complex series of handshakes from completing successfully.
* It requires generating, distributing, and regularly updating certificates on an ongoing basis. This process can be labor-intensive and requires meticulous management and coordination with trading partners. Any lapse in the process leads to transaction processing downtime.
* Once set up, AS2 servers are typically inefficient at processing large files and high transaction volume.
### Why trading partners still want AS2
Regardless of its drawbacks, trading partners – particularly in the retail space – often push for AS2 as a preferred connection type. There are several reasons for this preference.
* **Historical:** When AS2 was first developed, it was positioned as way to move from closed, proprietary VANs (Value-Added Networks) to internet-based EDI. AS2 provided a way for retailers and suppliers to circumvent VANs and connect directly. Many retailers today still associate AS2 with "direct connectivity," despite the fact that SFTP provides a functionally identical but more modern mechanism.
* **Real-time communication:** There's a perception amongst retailers that AS2 connections are faster than SFTP. When an AS2 message is sent from one a retailer to its supplier, the supplier's AS2 server receives the message in real-time. In contrast, when a retailer places a file on its SFTP server, it's up to the supplier to pick up the file at their own discretion. Many legacy EDI platforms are unable to poll faster than 30 minute intervals, which slows down the flow of transactions. By default, Stedi polls for files at 5-minute intervals, and can poll as often as once per minute (though we don't recommend a one-minute interval because retailer SFTP servers are often quite slow and the poller can't finish processing the first polling request by the time the second request is initiated).
### Why we recommend SFTP instead
Modern data transmission technologies have now made many AS2 features obsolete. For the following reasons, we strongly recommend using SFTP instead of AS2 when possible.
* **Security:** SFTP, built on SSH (Secure Shell), provides robust encryption and secure data transfer capabilities. This makes the encryption aspect of AS2 less unique, as SFTP offers similar security features.
* **Authentication:** SFTP supports strong authentication mechanisms and ensures data integrity during transfer. This diminishes the advantages of AS2 digital signature and MDN features.
* **Ease of use and maintenance:** SFTP is generally considered easier to implement and maintain - there are no certificates to update or MDNs to manage.
* **Network compatibility:** SFTP is widely compatible with various network configurations and firewalls, making it more adaptable across different IT environments than AS2.
* **Performance and scalability:** SFTP tends to be more performant and scalable, especially for larger files or higher volumes of data transfer.
# Connections overview
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections
***
title: Connections overview
sidebarTitle: Connections overview
----------------------------------
You can use Connections to exchange EDI files with trading partners via SFTP, FTPS, FTP, or AS2.
## Prerequisites
Before adding a connection, you need to set up a [partnership](/edi-platform/configure/trading-partners/profiles-and-partnerships).
## Create a connection
To create a connection:
1. Go to the [**Trading partners**](https://portal.stedi.com/app/core/partnerships) page.
2. Click the partnership where you want to add the connection.
3. Click **Create connection**.
4. Select the desired **Connection type**.
### Connection types
The available connection types are [Stedi SFTP/FTPS](/edi-platform/configure/trading-partners/connections/stedi-ftp), [Remote SFTP/FTPS](/edi-platform/configure/trading-partners/connections/remote-ftp), and [AS2](https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/as2/as2-overview).
The connection type you choose depends on your and your trading partner's requirements. Visit [Choosing a connection type](/edi-platform/configure/trading-partners/connections/choosing-the-right-connection-type) for our recommendations and details about the pros and cons of each type.
### Inbound file encoding
By default, Stedi generates EDI files with UTF-8 encoding and assumes UTF-8 encoding for inbound files.
However, some trading partners may send files containing extended Latin characters, such as `ä`, `é` or `ñ`. Files with Latin characters may be encoded in an **extended** ASCII encoding, such as Windows-1252. In these cases, you should specify the appropriate file encoding to ensure Stedi interprets the data correctly.
To set the file encoding for inbound EDI files, click a connection to go to its details page. In **Inbound settings** choose a **File encoding** format. Stedi supports UTF-8 and Windows-1252.
UTF-8 is backward compatible with ASCII-encoded files and suitable for most
cases. We recommend leaving this setting as the default unless your trading
partner tells you otherwise.
### ISA validation options
The ISA validation option determines how Stedi will validate ISA qualifiers and IDs in inbound EDI files received over the connection.
The **Default** option is the right choice for most use cases, and we strongly recommend speaking with customer support before changing it. The other options make troubleshooting more difficult in your account, but can enable some specific use cases.
* **Default**: Stedi attempts to match the ISA qualifiers and IDs in the inbound file with the local and partner profiles in any partnership within your account. Stedi uses the transaction settings in the matching partnership to validate and process the transactions in the file. Files that don't match any existing partnership will error.
* **Connection fallback:** When an inbound file's ISA values don't match any partnership in your account, Stedi uses this connection's partnership for processing. Files with multiple different ISA qualifiers and IDs will error.
* **Ignore ISA validation:** Stedi always assigns inbound files to this connection and processes them using the transaction settings on this connection's partnership, regardless of the ISA values. This option is useful when you need to ingest files containing an ever-growing list of unpredictable ISA qualifiers and IDs over the same connection. Note that you shouldn't use this option instead of creating a bounded number of predictable partnerships. For example, you shouldn't use this instead of creating partnerships for 100 known trading partners. Only choose this option if you're ingesting EDI files from external systems that constantly generate new ISA IDs, and those ISA IDs don't represent discrete trading partners.
## Next steps
After you create a connection, we recommend creating [transaction settings](/edi-platform/configure/trading-partners/transaction-settings) that define the EDI transactions you plan to exchange with your trading partner.
# Remote SFTP/FTPS Connections
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/remote-ftp
***
title: Remote SFTP/FTPS Connections
sidebarTitle: Remote SFTP/FTPS
------------------------------
Stedi connects to an external SFTP, FTP, FTPS server to exchange files with your trading partner. This could either be a server that your trading partner hosts, or a server that you host outside of Stedi on existing infrastructure. This is the most common connection type to use, since most large trading partners will require you to connect to their server instead of using yours.
Your trading partner will provide you with the connection information required to set up the connection. This typically includes the server address, port, username, and password or private key.
## Create Remote SFTP/FTPS connections
To create a Remote SFTP/FTPS connection:
1. Select **Remote SFTP/FTPS** as the **Connection Type**.
2. Stedi generates an internal **Connection name**. This is never visible to your trading partner and is used for unique identification with your Stedi account only. You can specify a custom name if desired. You cannot edit the name after the connection has been created.
3. Leave **ISA validation options** as **Default** unless you're very sure you need a different setting for your use case.
4. Enter the **Host** (the remote server address) and specify the **Port**.
5. Enter authentication credentials. Enter a **Username**, and either a **Password** or a **private key** from your local machine.
6. Specify the **Root directory** to use in the remote server.
7. (Optional) Use the **Advanced** menu if you need to specify the number of **Retries**, the **Connection timeout**, the **Socket timeout**, and **SFTP algorithms** to use.
> **Note:** We recommend using the default settings for the majority of use cases. Contact [support](https://www.stedi.com/contact) if you are unsure what settings to use and we'd be happy to help you figure out the right settings.
8. Configure **Inbound settings**.
* Set the remote directory where Stedi should retrieve inbound EDI files from your partner. You can use the suggested default if your partner has not provided a specific directory. Stedi only looks for files in this specific directory, it does not search for files within sub-directories.
* Use the toggles to set:
* How often to poll the remote server
* Whether to retrieve only new files created since the last fetch
* Whether to delete files after retrieval.
9. (Optional) Set a **Filter pattern** (regex expression) that Stedi will use to retrieve and process files. Stedi only processes files that match the regex criteria.
10. (Optional) Choose a **File encoding** format. We recommend leaving this as UTF-8 unless you know your partner will be sending files with a different encoding type.
11. Set the the remote directory in **Outbound settings** where Stedi should put generated EDI files for your partner to retrieve. You can use the suggested default if your partner has not provided a specific directory.
12. Click **Create connection** to save the connection.
You can now associate this connection with one or more [transaction settings](/edi-platform/configure/trading-partners/transaction-settings) and use it to exchange files with your trading partner.
## Shared connections
Stedi supports shared remote SFTP/FTPS connections, which allow you to use the same remote server across multiple partnerships. How you configure shared connections depends on your use case.
### Different directory per partner
If each trading partner adds files to a distinct directory on the server, configure the remote SFTP/FTPS connections on each partnership to poll the appropriate directory.
### Single directory for all partners
If all of your trading partners use the same root directory on the remote server, we recommend the following configuration:
1. Create remote SFTP/FTPS connections in each partnership with automatic polling disabled.
2. Create a separate partnership between your local profile and a new partner profile called `REMOTESFTP` or `REMOTEFTPS`.
3. Add a remote SFTP/FTPS connection to the new partnership and configure it to poll the shared remote server. You do not need to configure any other settings within the partnership.
This configuration allows you to easily identify which partnership's connection is polling, making debugging easier.
When Stedi polls the remote server, it automatically retrieves and processes all files that match the [filter pattern](#filter-pattern-for-inbound-files) (if set). During processing, Stedi first associates a file with the correct partnership and then processes the file according to that partnership's transaction settings. This process allows Stedi to process all files on the remote server, even if they are not associated with the partnership connection doing the polling.
## Test the connection
We recommend testing your connection immediately after creation to ensure you can connect to the remote server. To test the connection:
1. Go to the Partnership and click the **ellipses (...)** next to the SFTP/FTPS connection.
2. Select **Test**.
3. Stedi will attempt to connect to the remote SFTP/FTPS server using the credentials provided in your connection and will show a success or error message accordingly.
## Fetch files manually
You can disable automatic polling and retrieve files manually when needed. For example, you may want to retrieve files manually when testing or troubleshooting the connection.
To manually fetch files:
1. Go to the Partnership and click the **ellipses (...)** next to the connection.
2. Select **Fetch now**.
## Filter pattern for inbound files
You can specify a **Filter pattern** (regex expression) for Stedi to use when retrieving inbound files from the Remote SFTP/FTPS connection. When polling the remote server, Stedi only processes files that match the filter pattern.
For example, your trading partner may place files for multiple different entities on the remote server, with different prefixes for each entity. In this case, you could write a regex expression that matches only files with a given prefix.
To validate that the expression matches your expectations, you can **Fetch files manually** or wait until the next automatic polling attempt.
### Use cases
When you configure a remote FTP connection, you can define a polling interval. If there are files on the remote server under the `inbound` directory that you do **NOT** want to bring over to Stedi when polling, you can define a filter pattern to limit the files that Stedi processes. This is useful when you want to store other file types for different purposes in the folder you have selected to poll. For example, you might store CSV files, images, PDFs, etc.
In rare instances, your trading partner might **require** you to configure the inbound subdirectory to be the same as the outbound subdirectory. In this case, it is important that you configure a filter pattern to prevent Stedi from ingesting and processing the outbound files you send to your trading partner. Your filter pattern should identify the naming structure you expect to receive from the trading partner, and you need to make sure that this structure is sufficiently different from the naming structure you use for sending outbound files.
### Example
The following expression matches a filename like `INTERCHANGE-GROUP-20231115154001-681896da.edi`, and would prevent Stedi from processing files with names like `INTERCHANGE-681896da.edi` or `681896da.x12`.
`^(?\w+)-(?\w+)-(?\d+)-(?\w+).edi$`
## Status and logs
Each Remote SFTP/FTPS connection's status and logs can be found on its overview page. To view the overview page, go to the partnership and click the connection's name.
An **Available** connection status indicates that Stedi is able to connect to the remote server.
The **Logs** detail each connection and polling attempt.
## Static IPs
Enabling a static IP address ensures that your Remote SFTP/FTPS connections always use the same source IP address when communicating with a remote server. This may be required if one or more of your trading partners need to add your IP address to an allowlist to enable access.
You can enable a static IP address from the [EDI Settings](https://portal.stedi.com/app/core/settings) page.
# Stedi SFTP/FTPS Connections
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/stedi-ftp
***
title: Stedi SFTP/FTPS Connections
sidebarTitle: Stedi SFTP/FTPS
-----------------------------
Stedi creates and hosts a fully-managed server that supports both SFTP and FTPS protocols, along with user credentials you can provide to your trading partner. Your trading partner can use their credentials to connect to the server through either SFTP (using port 22), or FTPS (using port 21).
Once you configure the connection, Stedi automatically ingests and processes any files that your trading partner adds to the server and automatically places outbound EDI files on the server for your trading partner to retrieve.
This is the easiest way to get started exchanging EDI files with the least amount of configuration. However, your trading partner may require you to use their server instead, especially if they are the larger party.
The Stedi SFTP/FTPS connection type supports only username and password
authentication. If your trading partner requires key-based authentication, you
can use a [Remote SFTP/FTPS
connection](/edi-platform/configure/trading-partners/connections/remote-ftp)
instead.
## Create SFTP/FTPS connections
To create a Stedi SFTP/FTPS connection:
1. Select **SFTP/FTPS** as the **Connection type**.
2. Stedi generates an internal **Connection name**. This is never visible to your trading partner and is used for unique identification with your Stedi account only. You can specify a custom name if desired. You cannot edit the name after the connection has been created.
3. Leave **ISA validation options** as **Default** unless you're very sure you need a different setting for your use case.
4. If required, provide a specific length for the autogenerated password.
5. Specify an **Inbound directory**. This is the directory that your trading partner will use to send files to you. Any file placed in this directory will be automatically ingested and processed. The default directory is `/inbound` but you can specify a different directory if needed.
6. Specify an **Outbound directory**. This is the directory that your trading partner will use to retrieve files from you. Outbound EDI files will be automatically deposited in this directory. The default directory is `/outbound` but you can specify a different directory if needed.
7. By default, **Delete inbound files on receipt** is selected. Typically, partners want you to delete files after processing. If you want to keep the files, deselect this option.
8. Click **Create connection**. Stedi shows the login credentials for the created user.
**Important:** The login credentials will only be displayed once and cannot be
retrieved again for security reasons. We recommend immediately saving the
login credentials in a secure location such as a password manager. If needed,
you can always [regenerate new credentials](#regenerate-credentials).
You can now associate this connection with one or more [transaction settings](/edi-platform/configure/trading-partners/transaction-settings) and use it to exchange files with your trading partner.
## Regenerate credentials
To generate new login credentials:
1. Navigate to the **Trading partners** page.
2. Click the partnership that contains the connection whose credentials you want to regenerate.
3. Click the **Edit** button.
4. Under the **Username** field, click **Regenerate credentials**.
## Static IPs
Some partners will need to know Stedi SFTP/FTPS's IP addresses in order to allow internal systems to establish a connection. Stedi SFTP/FTPS uses the following IPs:
`18.119.51.218` and `18.206.132.233`
These IPs apply only to Stedi-hosted SFTP/FTPS. You can enable different
static IPs for Remote SFTP/FTPS in [EDI
Settings](/edi-platform/configure/global-settings).
## Status and details
You can find details about each Stedi SFTP/FTPS connection on its overview page. To view the overview page, navigate to the partnership and click the connection's name.
# Element data types in X12 EDI
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/x12/elements/element-data-types-in-x12-edi
***
title: 'Element data types in X12 EDI'
sidebarTitle: 'Elements - Data types'
-------------------------------------
All [elements in X12](https://www.stedi.com/edi/x12-008010/element) have a specific data type: elements can be a string (i.e., alphanumeric), number, decimal, date, time, code, or binary. These data types dictate the kind of data that can be sent in a specific element and how it should be treated by external systems ingesting the EDI.
## String/Alphanumeric (AN)
Elements with the `string` data type are symbolized by the code `AN`. Strings may contain any sequence of characters, including letters, digits, spaces, punctuation marks, spaces, tabs, and/or special characters.
Typically, elements with the string data type are used in free-form fields, where the element name or description explains what information should be contained in the element, and how to interpret it.
While elements with a string data type can support any character, they must not contain the element separator (often `*`), sub-element separator (often `^` or `:`), or segment terminator (often `~`) specified in the envelope; those are reserved solely for those functions. Furthermore, for any EDI transaction that specifies a release character in the `ISX` segment (v7040 or later), you cannot use that release character in any element.
**Examples of `string` elements include:**
* Red
* Working hours: from 9AM to 5PM
* New York
* X253N0123
## Numeric (N0, N2, N4, N6)
Elements with the `numeric` data type are symbolized by `N`. All elements with a numeric data type must contain only digits and an optional minus (-) sign to indicate a negative value.
The `N` indicates that the data type is numeric, and the `0`, `2`, `4`, or `6` indicate the number of implied decimal positions. `N0` implies the number is an integer (i.e., whole numbers), `N2` implies the number contains two decimal positions, `N4` implies the number contains four decimal positions, and `N6` implies the number contains six decimal positions,
For example, if a number is sent in an element with the data type `N0`, it should be interpreted as a whole number, exactly as it is shown.
**Examples of `N0` elements include:**
* 1
* 100
* -645
* 812
If a number is sent in an element with the data type `N2`, it should be interpreted as if it has two decimal places.
**Examples of `N2` elements include:**
* 123.45 would be sent as 12345
* -5 would be sent as -500
* 100 would be sent as 10000
In practice, the `N2` data type is often used in elements that describe a monetary amount. For example, the [610 (Amount)](https://www.stedi.com/edi/x12-008010/element/610) element is used in the [TDS01](https://www.stedi.com/edi/x12-008010/segment/TDS) to represent the invoice total amount, and has a data type of `N2`. This implies the value of `TDS01` has two decimals. For example: `TDS*1000` implies a dollar value of `$10`, not `$1000`.
## Decimal number (R)
Elements with the `decimal number` data type are symbolized by the code `R`. In an element with a decimal data type, decimals are optional for all integers, but are required for all fractional values. Decimal numbers also support a leading minus (-) sign, if needed, whereas the absence of a minus sign implies a positive value. Therefore, the plus sign (+) should not be transmitted.
The minus sign and the decimal point are not counted when determining the length of the data element. Additionally, all leading zeros in an element with a decimal number type should be suppressed, unless needed to satisfy minimum length requirements.
**Examples of `decimal` elements include:**
* 12.345
* 2000
* 765.000
* -95
## Dates (DT)
Elements with the `date` data type are symbolized by the code `DT`. Based on the X12 version, data formats are treated differently.
Before v4010, all dates were in the `YYMMDD` format, where `YY` represents the last two digits of the calendar year, `MM` represents the month (01 to 12), and `DD` represents the day of the month (01 to 31).
**Examples of dates in `YYMMDD` format include:**
* `980127`, which indicates `January 27th, 1998`
* `220815`, which indicates `August 15th, 2022`
Starting from v4010, all dates are represented in the `CCYYMMDD` format, where `CC` represents the first two digits of the calendar year, `YY` represents the last two digits of the calendar year, `MM` represents the month (01 to 12), and `DD` represents the day of the month (01 to 31).
**Examples of dates in `CCYYMMDD` format include:**
* `20230202`, which indicates `February 2nd, 2023`
* `20220120`, which indicates `January 20th, 2022`
**Note:** The [ISA09 (interchange date)](https://www.stedi.com/edi/x12-008010/segment/ISA) only supports the `YYMMDD` date format, regardless of which X12 version is used.
## Time (TM)
Elements with the `time` data type are symbolized by the code `TM`. Time in the X12 standard is expressed in a 24-hour clock format (e.g.,`HHMM`, `HHMMSS`, `HHMMSSD`, or `HHMMSSDD`). `HH` is the numeric expression of the hour (00 to 23), `MM` is the numeric expression of the minute (00 to 59), `SS` is the numeric expression of the second (00 to 59), and `DD` is the numeric expression of the decimal seconds. Decimal seconds are expressed as follows: `D` = tenths (0 to 9) and `DD` = hundredths (00 to 99).
**Examples of `time` elements include:**
* `1845`, which represents `18:15` in `HHMM` format
* `091530`, which represents `09:15:30` in `HHMMSS` format
* `10220302`, which represents `10:22:03:02` in `HHMMSSDD` format
**Note:** Time elements are often accompanied by another element in the same segment, indicating which timezone the time is in.
## Identifier (ID)
Elements with the `identifier` data type, sometimes referred to as a `code`, are symbolized by the code `ID`. An element with an `ID` data type must always contain a value from a predefined list of values that is maintained by X12, other bodies that are recognized by X12, or are universally known (e.g., Standard Carrier Alpha Codes (SCACs), or state/province codes). The intent of the identifier data type is to allow computers to validate data elements based on a standard list of codes, without having to agree upon the meaning of each code.
For the elements that contain a predefined list of X12 identifiers, each one has a code and a description (e.g., `ST` and `Ship To`). An *extended code definition*, which provides additional information to help explain the meaning of the code, may also be supplied in addition to the identifier description.
**Examples of pre-defined X12 `identifier` codes include:**
* `ST` - ship to
* `Z7` - mark for party
* `YC` - bail payor
In addition to elements with a predefined list of X12 identifier codes, there are several elements that have the `ID` data type without a predefined list. Here are some examples:
* Element [156 (State or province code)](https://www.stedi.com/edi/x12-008010/element/156) should contain the two-digit code of a US state (e.g., `CA` for California), Canadian provinces (e.g.,`ON` for Ontario), or any other state/province/region code specific for a given country (must be exactly two characters).
* Element [26 (Country Code)](https://www.stedi.com/edi/x12-008010/element/26) should contain a two-letter country code defined by ISO 3166 (e.g., `US` for the United States of America, `IN` for India).
* Element [140 (SCAC)](https://www.stedi.com/edi/x12-008010/element/140) should contain a two- to four-character code that represents a carrier, as defined by the National Motor Freight Traffic Association (NMFTA). However, in practice, SCACs are often sent as mutually agreed upon values.
While X12 is standardized, in practice, many trading partners will deviate from these predefined lists. X12 provides a mechanism for doing this, by supporting “mutually-defined” codes, signified by the codes `Z`, `ZZ`, or `ZZZ`. While mutually-defined codes are available, some trading partners might choose to “break” the X12 standard by utilizing their own custom codes and descriptions in their implementation guides. Lastly, some trading partners will interpret the predefined codes differently (e.g., they will use the `WH` (warehouse) qualifier code, as opposed to the `SF` (ship from) code).
## Binary (B)
Elements with the `binary` data type are symbolized by the code `B`. A binary data element contains a sequence of bytes. Those bytes may include characters that normally have special meaning, like the segment separator, or the element separator. For that reason, binary data isn’t parsed like the rest of the X12 document. Instead, binary data always comes with a length, so that it’s clear where the binary data ends.
There are only a few segments with a binary data element.
* [BIN](https://www.stedi.com/edi/x12/segment/BIN) is used to transfer files. It always comes as part of a loop that also include the [EFI](https://www.stedi.com/edi/x12/segment/EFI) segment. `EFI` contains the metadata of the file, `BIN` contains the contents.
* [BDS](https://www.stedi.com/edi/x12/segment/BDS) (v4020 and up) is also used to transfer files, but it’s paired with [OOI](https://www.stedi.com/edi/x12/segment/OOI) instead of `EFI`. `OOI` is a more flexible way to encode a file’s metadata. Unlike `BIN`, `BDS` includes an element that tells you how the binary data is encoded, for example base64, uuencoding, no encoding, etc.
* [S3S](https://www.stedi.com/edi/x12/segment/S3S) and [S4S](https://www.stedi.com/edi/x12/segment/S4S) are used for sending data securely. They both use binary (v4020 and up) to send encrypted and/or compressed data.
Stedi supports reading and writing binary encodings that are valid UTF-8 strings such as ASCII and Base64. It does not support unfiltered binary data.
# Element Requirements in X12 EDI
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/x12/elements/element-requirements-in-x12-edi
***
title: 'Element Requirements in X12 EDI'
sidebarTitle: 'Elements - Requirements'
---------------------------------------
When an [element](https://www.stedi.com/edi/x12-008010/element) is in the context of a [segment](https://www.stedi.com/edi/x12-008010/segment), the X12 standard specifies three types of element requirements: mandatory, optional, or conditional. In addition to the requirements given by X12, trading partners will often deviate slightly from the standard to suit their business needs. This is both expected and valid.
Trading partners share these requirements as *implementation guides*, usually via PDF. Most X12 implementation guides used in the industry were built using a tool called SpecBuilder, which creates a standard PDF format. We will use SpecBuilder PDFs and their terminology to explain element requirements below, but your trading partner might send these requirements in different format (e.g., CSV, Word, custom PDF).
In these implementation guides, the element requirements given by X12 are found in a column called *Requirement* (or *Req* for short). The *Req* column displays these requirements as `M` for mandatory, `O` for optional, and `C` or `X` for conditional. If a trading partner deviates from the specifications given by X12, those deviations are usually found in a column called *Usage* or *Attributes*, and they use a different syntax, like `Must use`, `Used`, and `Dependent`.
## X12 types
### Mandatory
Mandatory elements are marked with an `M` in most implementation guides, but `R` (required) is used as well. If an element is defined as mandatory in a segment, then you cannot send X12 data without it. In most cases, transactions that are missing mandatory elements will either be stopped by the sender or rejected by the recipient.
For example, the `BIG01` (Invoice Date) and the `BIG02` (Invoice Number) in the [BIG segment](https://www.stedi.com/edi/x12-008010/segment/BIG) used in all [X12 810 Invoices](https://www.stedi.com/edi/x12/transaction-set/810) are mandatory elements. You cannot send an invoice without the invoice number and date.
### Optional
Optional elements are marked with an `O` in most implementation guides.
These elements sometimes carry additional information in the notes section of the PDF, such as when the element should be used. If an element is marked as optional, it can be omitted in the data and the transaction would still be valid.
For example, the `BIG03` (Purchase Order Date) and `BIG04` (Purchase Order Number) in [X12 810 Invoices](https://www.stedi.com/edi/x12-008010/810) are optional elements. According to X12, you can send an invoice without the corresponding purchase order number and date, and it would still be a valid transaction.
### Conditional
Conditional elements, marked with either a `C` or an `X`, are a special case. Their usage depends on the other elements within the same segment. In some situations these elements might be mandatory, and in others – optional.
Whenever there is an element marked with a `C` or an `X`, there will be a corresponding *Syntax Rules* block on the same page. For example, on the `DTM` segment page below, the syntax rules appear below the last element definition.
In order to understand how and when to use an element that is marked as conditional, you first need to understand the X12 syntax rule used. Every syntax rule begins with an identifier: `P`, `R`, `E`, `C`, or `L`. The identifier is followed by two or more elements involved in the condition, where each element occupies two digits (e.g., `01`, `05`, `11`).
**Conditional rule definitions:**
| Letter | Name | Condition | Example |
| ------ | ---------------- | ----------------------------------------------------------------------------------------- | ------- |
| P | Paired | If the first element is present, then all the other elements must be present. | P0102 |
| R | Required | At least one of the elements must be present. | R020304 |
| E | Exclusive | Only one of the elements may be present. | E0305 |
| C | Conditional | If the first element is present, then all the other elements must be present. | C0102 |
| L | List conditional | If the first element is present, then at least one of the other elements must be present. | L010308 |
## Trading partner specific element requirements
The element requirements defined by the X12 standard dictate which elements are optional, mandatory, or conditional when used in a segment. However, most businesses do not use all the elements in the standard - and for those that they use, they often need to change their requirements. As such, they use the elements, and change their requirements, to best serve their business requirements.
For example, your trading partners may decide that some elements—whether optional or conditional as per the standard—must be present in the data (e.g., are mandatory). On the other hand, this does not work in reverse; according to the X12 standard, you cannot mark elements that are mandatory as optional or conditional in your guide. In practice, some businesses break the X12 standard and ask trading partner's to conform to their specification nonetheless.
When a trading partner deviates from the base X12 specification, their implementation guide will usually contain a column titled *Usage* or *Trading Partner Name Requirements*. Instead of using the typical `M`, `O`, `C`, and `X` syntax, they will use other terms like `Must Use`, `Used`, or `Dependent`.
Below is an example of an [MEA (Measurement) segment](https://www.stedi.com/edi/x12/segment/MEA) with multiple elements and composite elements which are considered optional or conditional by the X12 v4010 standard, but all marked as `Must use`:
Below is a table which explains the relationship between the customer defined usage and standard X12 codes:
| Customer Defined Usage | Equivalent X12 type | Definition |
| ---------------------- | ------------------- | ----------------------------------------------------------------------- |
| Must Use | M | May be sent on the EDI transaction |
| Used | O | May be sent on the EDI transaction |
| Not used | N/A | Must not be sent on the EDI transaction |
| Recommended | O | Should be sent on the EDI transaction |
| Not Recommended | N/A | Should not be sent on the EDI transaction |
| Future | N/A | Should not be sent on the EDI transactions, but reserved for future use |
| Dependent | C or X | Conditional based on syntax rules |
When you are building EDI integrations, make sure you pay close attention to element requirements, and how they deviate from the base X12 standard.
# Relational conditions in X12 EDI
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/x12/elements/relational-conditions-in-x12-edi
***
title: 'Relational conditions in X12 EDI'
sidebarTitle: 'Relational conditions'
-------------------------------------
All [elements](https://www.stedi.com/edi/x12-008010/element) in the X12 standard can be marked as mandatory (`M`), optional (`O`), or Conditional (`C` or `X`). If an element is marked as conditional, its usage depends on the presence (or absence) of other elements in the same segment. These relational conditions are described using a specific X12 syntax and are usually found in the implementation guide shared between trading partners. While relational conditions were touched on briefly in [Element Requirements in X12 EDI](https://www.stedi.com/edi/essentials/x12/elements/element-requirements), this article provides a more in-depth analysis of the subject.
## Overview
If an element is marked as conditional, that condition is governed by the associated syntax rule. Every syntax rule begins with an identifier: `P`, `R`, `E`, `C`, or `L`. Each identifier is then followed by two or more elements involved in the condition, where each element is referred to by its position in the segment (e.g., `01`, `05`, `11`), and each element position occupies two digits. For a given segment, there can be one or more syntax rules, and a single element can be associated with one or more syntax rules inside a single segment.
The table below describes the meaning of each rule:
| Letter | Name | Condition | Example |
| :----- | :--------------- | :---------------------------------------------------------------------------------------- | :------ |
| P | Paired | If the first element is present, then all the other elements must be present. | P0102 |
| R | Required | At least one of the elements must be present. | R020304 |
| E | Exclusive | Only one of the elements may be present. | E0305 |
| C | Conditional | If the first element is present, then all the other elements must be present. | C0102 |
| L | List conditional | If the first element is present, then at least one of the other elements must be present. | L010308 |
## Paired (P)
If a syntax rule starts with `P`, it is a *paired condition*. This condition means that if any element in the rule is present in the segment, then all the other element(s) in the rule must be present as well.
A typical example of when a paired syntax rule is used is when one element describes the meaning of another. For example, elements [N103 (Identification Code Qualifier)](https://www.stedi.com/edi/x12-008010/element/66) and [N104 (Identification Code)](https://www.stedi.com/edi/x12-008010/element/67) are always paired, which is indicated by the syntax rule `P0304`. This means that if one of them is present, then the other must be present as well.
These two elements are paired because only sending one element would not make sense without the other. In this example, the `N103` “qualifies” the `N104` – it explains who or what entity assigned the identification code. Providing just the qualifier or just the identification code does not provide a trading partner with enough information, so they must be sent together.
**The description of the paired syntax rule always follows this format:**
* If either \{XX}, \{YY},..., or \{ZZ} is present, then the other is required.
## Required (R)
If a syntax rule starts with `R`, it is a *required condition*. This condition means that at least one of the elements listed in the rule must be present in the segment. Typically, a required syntax rule is used when there are multiple positions within a segment to provide the necessary information, but not all elements are needed to communicate that information.
A good example of a required syntax rule is in the [TXI (Tax Information) segment](https://www.stedi.com/edi/x12-008010/segment/TXI). This segment contains the R020306 syntax rule, which indicates that at least one of `TXI02` (Monetary Amount), `TXI03` (Percent), or `TXI06` (Tax Exempt Code) is required. This means that you can provide the tax amount (e.g., $18.65), the tax percent (e.g., 12%), the code that explains tax exemption (e.g., `F`, Exempt from Goods and Services Tax), or all three - but you have to supply at least one, otherwise it will not convey enough information.
**The description of the required syntax rule always follows this format:**
* At least one of \{XX}, \{YY},..., or \{ZZ} is required.
## Exclusive (E)
If a syntax rule starts with `E`, it is an *exclusive condition*. Only one of the elements in the syntax rule may be present, but no others.
Typically, an exclusive syntax rule is used when there are multiple elements in a segment that, if sent together, would cause a conflict in interpretation. A good example of an exclusive syntax rule is in the [G72 (Allowance or Charge) segment](https://www.stedi.com/edi/x12-008010/segment/G72). This segment contains a `G7205` (Allowance or Charge Rate), a `G7208` (Allowance or Charge Total Amount), and a `G7209` (Allowance or Charge Percent). Because an allowance or charge can only be indicated as a unit rate, a total amount, or a percent (but not as more than one), these elements cannot be sent together.
**The description of the exclusive syntax rule always follows this format:**
* Only one of \{X}, \{Y},..., or \{Z} may be present.
## Conditional (C)
If a syntax rule starts with `C`, it is a *conditional rule*. If the first element listed in the rule is present, then the subsequent elements must be present as well.
Typically, conditional rules are used because the first element listed in the rule cannot stand on its own; It is only useful when the subsequent elements are present. An example of a conditional rule is when there are two elements in the rule, and the first element listed provides added context to the second element. This is different from a paired syntax rule because the second element listed could stand on its own without the first element, whereas the first cannot.
For example, the [DTM (Date/Time Reference) segment](https://www.stedi.com/edi/x12-008010/segment/DTM) has a `C0403` syntax rule. This rule states that if the `DTM04` (Time Code) is present then the `DTM03` (Time) is required. A time code in this case is synonymous with “time zone” (e.g., PT, ET, IST, etc.). As such, if the time code is present, but no time is present, then the time code is useless. However, if the `DTM03` (Time) is present, then the time code is not necessarily required (but in this case, could be ambiguous).
**The description of the conditional syntax rule always follows this format:**
* If \{X} is present, then \{Y} is required.
## List conditional (L)
If a syntax rule starts with `L`, it is a *list conditional rule*. If the first element in the rule is present, then at least one of the other elements listed in the rule is required. There must always be three or more elements in a list conditional rule, otherwise, a conditional syntax rule should be used.
Typically, list conditional rules are used because the first element cannot stand on its own, and there are multiple other elements in the segment that can be used to provide the necessary information. For example, the [ITD (Terms of Sale/Deferred Terms of Sale) segment](https://www.stedi.com/edi/x12-008010/segment/ITD) contains the `L03040513` rule. This means that if the `ITD03` (Terms Discount Percent) is present, then at least one of `ITD04` (Terms Discount Due Date), `ITD05` (Terms Discount Days Due), or `ITD13` (Day of Month) is required.
Because the terms discount percent given in the `ITD03` needs an associated date, then one of the terms (i.e., discount due date, the terms discount days due, or the day of the month) is required in order to convey the information necessary to the recipient. As with conditional rules, the presence of `ITD04`, `ITD05`, or `ITD13` does not make `ITD03` required.
**The description of the conditional syntax rule always follows this format:**
* If \{X} is present, then at least one of \{Y},..., or \{Z} is required.
# What is an element in X12 EDI?
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/x12/elements/what-is-an-element
***
title: 'What is an element in X12 EDI?'
sidebarTitle: 'What is an element?'
-----------------------------------
[Elements](https://www.stedi.com/edi/x12-008010/element) in X12 EDI are the primary source of information exchanged in an EDI transaction. [Segments](https://www.stedi.com/edi/x12-008010/segment) logically group elements together in order to convey specific information. You will always see elements inside of a segment, and elements are separated from the segment and other elements by delimiters (e.g., `*`, `|`, etc.).
Outside the context of a segment, the X12 standard defines an ID, a name, description, data type, and min and max length for every element. These element attributes are fixed; they do not change, regardless of what segment the element is found in.
When an element is in the context of a segment, the X12 standard provides additional attributes, such as the element’s position and its requirement. These attributes are variable; they change based on which segment the element is contained in.
For example, each element in the [BEG segment](https://www.stedi.com/edi/x12-008010/segment/BEG) below has its own fixed attributes, and then additional attributes based on the fact they are used in the `BEG` segment. For example, the [373 Date element](https://www.stedi.com/edi/x12-008010/element/373) always has the `date` data type and a min and max length of eight characters; but when it is used in the fifth element of the `BEG` segment (e.g., the `20220610` below), it is always mandatory.
`BEG*00*NE*080032**20220610~`
## Element attributes
### IDs
Each element is given a unique ID that can be one to four characters in length. There are more than 2,000 unique elements in the X12 EDI standard. For example, the `Purchase Order Type Code` element has the ID `92`, whereas the Date element has the ID `373`. The IDs of *simple* *elements* are numeric, but *composite data elements* are prefixed with a `C`, and elements found in interchange segments are prefixed with `I`.
You can see the full list of elements and their IDs [here](https://www.stedi.com/edi/x12/element).
### Names
Each element is given a name, which is a short, generic description of what data the element represents. For example, the name of the `324` element is `Purchase Order Number` and the name of the `100` element is `Currency Code`. While the element is given a unique element ID, in practice, the element name is used for identifying the element, not the ID.
You can see the full list of elements and their names [here](https://www.stedi.com/edi/x12/element).
### Descriptions and semantic notes
In addition to the element name, X12 provides a longer description to explain what the element represents and how it is used. For example, the `373` Date element has the following description: date expressed as `CCYYMMDD` where `CC` represents the first two digits of the calendar year.
When an element is in the context of a segment, X12 will occasionally provide semantic notes, which explain how that element is used specifically inside of the segment. For example, the `373` Date element has an extra note when it is in the `BEG` segment: in the `BEG`, the Date element (`BEG05`) is the date assigned by the purchaser to purchase order.
### Data types
All elements in X12 have a specific data type: elements can be a string (i..e., alphanumeric), number, decimal, date, time, code, or binary. These data types dictate the kind of data that can be sent in a specific element and how it should be treated by external systems ingesting the EDI.
**Note:** Element separators (often `*`), sub-element separators (often `^` or `:`), and segment terminators (often `~` or `\n`) cannot be used in any elements, regardless of data types.
| **Data type** | **Acronym** | **Description** | **Example** |
| --------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| String / Alphanumeric | AN | May contain any alphanumeric characters, including letters (upper & lowercase), numbers, punctuation marks, spaces, and more. | - Red
- Working hours: 9 a.m. to 5 p.m.
- X355SNHM
|
| Number | N0, N2 | Must contain only digits (no decimals), and can contain a minus sign for negative values. The N indicates it is a number, and `0` or `2` indicates the number of implied decimal points. N0 is used for integers, and N2 is used to imply two decimal points. | N0 N2 - 81342 (equal to 813.42)
- -42 (equal to -0.42)
|
| Decimals | R | May contain numbers with decimal points (if needed) and a minus sign for negative values. | |
| Dates | DT | Date formats in X12 depend on trading partner specs and the version used. X12 versions before v4010 used YYMMDD format. After v4010, CCYYMMDD format is preferred, where CC represents the first two digits in the calendar year. `ISA09` (interchange date) is an exception and uses YYMMDD. | YYMMDD CCYYMMDD - 19980127 (`27 Jan 1998`)
- 20220926 (`26 Sep 2022`)
|
| Time | TM | Time is always expressed in 24-hour clock time as follows: HHMM, or HHMMSS, or HHMMSSD, or HHMMSSDD, where H = hours (00-23), M = minutes (00-59), S = integer seconds (00-59) and DD = decimal seconds; decimal seconds are expressed as follows: D = tenths (0-9) and DD = hundredths (00-99). Time elements are usually followed by a qualifier code representing time zone. | HHMM HHMMSS HHMMSSDD |
| Codes | ID | Most elements with "code" data types have a list of valid codes defined by the X12 standard. These codes are usually "qualifiers" or "values" that are shorthand for a value. Codes are never longer than 4 digits. Some codes are not provided by X12, like 156 (state or province code) or 24 (equipment type). | Qualifiers - ZZ (mutually defined)
- SF (ship from)
Values Non-X12 codes - US (United States)
- FHD (FedEx SCAC code)
|
| Binary | B | Elements with the binary data type may contain binary data (i.e., a string of octets which can assume any binary pattern from hexadecimal 00 to FF. Note: The maximum length is 15 characters for binary data. Only the BIN and BDS segments support elements with a binary data type. | |
To learn more about element data types in X12 EDI, [click here](https://www.stedi.com/edi/essentials/x12/elements/element-data-types).
### Length (min/max)
Each element is given a minimum and maximum length that they need to adhere to, as per the X12 standard.
The minimum and maximum length can vary from element to element. For example, some elements have fixed lengths like `NTE01` (Note Reference Code) which have a minimum and maximum length of three characters. On the other hand, some elements can contain a wide range of characters, like `NTE02` (Description), which supports a minimum of one character and a maximum of 80.
For elements with the decimal data type (`R`), the count of characters does not include the optional decimal point, minus sign, or trailing exponent indicator `E`.
**Note:** If an element is optional and is not used in a segment, the length restrictions do not apply.
### Position
When an element is used in a segment, it occupies a position in that segment. The X12 standard defines what element is used in every position of a segment. While elements can be referred to by their ID and name (e.g., the `373` Date element in the `BEG`), in-practice element positions are referred to by the segment acronym (e.g., `TDS`), followed by the position of the element in the segment (e.g., `01`). For example, the second element in the `TDS` is `TDS02`, and so on. This is useful for communicating trading-partner requirements, as you can refer to an element as the *TDS05*.
The same element can be found multiple times, in different positions of a single segment. The position, accompanied by semantic notes, determines how to use that element. For example, the element `610` (Amount) is used four times in the `TDS` segment, where the `TDS01` is the total amount of the invoice, and the `TDS04` indicates the total amount of terms discount.
**Note:** If an element is not present, it still occupies a position.
### Requirements
When an element is in the context of a segment, the X12 standard specifies three types of element requirements: mandatory, optional, or conditional. In addition to the requirements given by X12, trading partners will often deviate slightly from the standard to suit their business needs.
* **Mandatory**: Elements marked as mandatory (`M`) must be present in the segment.
* **Optional**: Elements marked as optional (`O`) may be present in the segment.
* **Conditional**: The presence of an element in a segment marked as conditional (`C` or `X`) is dependent on the relational condition syntax rule used.
To learn more about element requirements in X12 EDI, [click here](https://www.stedi.com/edi/essentials/x12/elements/element-requirements).
### Composite & component elements
A composite element contains a collection of component elements (also known as sub-elements). Component elements are functionally the same as the simple elements we explored above, only they have the composite element as the parent, not the segment.
Composite elements also have their own IDs, which begin with `C`. For example, `C040` (Reference Identifier) is a composite data element.
For composite elements, the same position notation (e.g., `REF04`) is used, however, for component elements, the position is given as the name of their parent composite element + `C` + position. For example, the second component element in `REF04` would be referred to as `REF04C02`.
# X12 HIPAA
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/x12/hipaa
***
title: "X12 HIPAA"
sidebarTitle: "HIPAA"
---------------------
X12 HIPAA is the common name for the set of specifications businesses use to transmit healthcare transactions in the United States.
A *transaction* is an electronic exchange of information between two parties to carry out financial or administrative activities related to healthcare. For example, a healthcare provider like a hospital may send a claim to a health plan to request payment for medical services.
X12 HIPAA is a narrower subset of the X12 standard. The name refers to the detailed specifications that the X12N Insurance subcommittee have defined. The official term for these specifications is a Technical Report Type 3 (TR3). More commonly, they are called X12 HIPAA implementation guides, though regulators call them federally-mandated operating rules.
## Where can I find X12 HIPAA specifications?
The [Stedi Network](https://www.stedi.com/edi/network) has [Stedi guides](https://www.stedi.com/docs/edi-platform/guides) for every X12 HIPAA transaction set. Stedi guides are interactive, machine-readable EDI specifications that let you instantly validate EDI test files.
You can import any HIPAA guide into your Stedi account and use it to validate and generate EDI. Visit our [Trust Center](https://trust.stedi.com/) to learn more about HIPAA compliance at Stedi.
## Is my trading partner's companion guide the same as an X12 HIPAA specification?
No. A companion guide such as [Anthem's 270/271 companion guide](https://www.anthem.com/docs/public/inline/EDI_CA_00021.PDF) is only an addendum and does not contain the complete information required to understand the specification.
To create a valid transaction, you also need the information contained in the X12 HIPAA implementation guide. Generally, you start with the X12 HIPAA implementation guide and then customize it further using the information in the companion guide.
Companion guides are allowed to be *more* restrictive than the X12 HIPAA implementation guides, but they cannot be *less* restrictive. For example, if the X12 HIPAA implementation guide says that a given field is required, a companion guide provided by a healthcare plan operator cannot say that the field is optional.
By the same token, the X12 HIPAA implementation guides are always more restrictive than the base X12 Release 5010 specification, and they can never be less restrictive.
## Does every healthcare company use the same specification?
No. There are two reasons why healthcare companies don't share the exact same specifications.
First, HHS so far has only mandated the strict use of X12 HIPAA implementation guides (also called operating rules) for a subset of transactions. Refer to the [Operating Rules Mandate](https://www.caqh.org/core/operating-rules-mandate) for complete details.
So, while many companies may choose to adopt the X12 HIPAA implementation guides as a restriction above and beyond the base X12 Release 5010 standard, X12 HIPAA is not strictly required for all transaction sets.
| Transaction Name | X12 Transaction Set | Federally Mandated Operating Rules |
| ---------------------------------------------------------------------------------- | ------------------- | ---------------------------------- |
| Eligibility and benefit verification | 270/271 | Yes |
| Claim status inquiry and response | 276/277 | Yes |
| Claim payment (EFT) / Electronic remittance advice (ERA) | 835 | Yes |
| Prior Authorization and referrals / Referral certification | 278 | No |
| Premium payment/explanation (employer) | 820 | No |
| Enrollment/disenrollment in a health plan | 834 | No |
| Health claims (institutional, professional, and dental) / coordination of benefits | 837 | No |
Second, even for transaction sets that have federally mandated operating rules, like the 270 and 271, companies are permitted to implement further constraints. These additional constraints are provided in a companion guide, such as the one Anthem provides for its [270/271](https://www.anthem.com/docs/public/inline/EDI_CA_00021.PDF).
## Why does healthcare use X12 HIPAA?
The United States Department of Health and Human Services (HHS) originally chose X12 as the mandated standard. Standardizing on X12 meant that all parties would use a common transaction structure, which would serve to minimize the industry's proliferation of multiple formats.
### X12 allowed too much flexibility
While HHS found that adopting X12 decreased administrative burden for parties by creating greater uniformity, the flexibility of the X12 standard meant that each health plan used the transaction set standards in different ways. Although the X12 standard constrained the data elements that could be used, an organization was free to impose additional constraints required by their business flow and operations, both in terms of technical constraints and business semantics.
For example, different health plan operators may have allowed for a different number of transactions to be submitted in a single file. They may also have had different opinions about which specific data elements are required for each transaction.
This led each health plan operator to create a companion guide, typically a PDF, that described their unique implementation of the X12 transaction sets. This required trading partners (the providers) to adhere to different transaction implementation rules for each plan operator, subverting the original goal of administrative simplification.
### X12 HIPAA reduces ambiguity
Congress passed laws in 2010 ([Public Law 111-148](https://www.govinfo.gov/content/pkg/PLAW-111publ148/pdf/PLAW-111publ148.pdf) | [Public Law 111-152](https://www.govinfo.gov/content/pkg/PLAW-111publ152/pdf/PLAW-111publ152.pdf)) requiring HHS to "adopt a single set of operating rules for each transaction\[...]with the goal of creating as much uniformity in the implementation of the electronic standards as possible." The laws mandate that these operating rules "describe all data elements (including reason and remark codes) in unambiguous terms, require that such data elements be required or conditioned upon set values in other fields, and prohibit additional conditions (except where necessary to implement State or Federal law, or to protect against fraud and abuse)."
Essentially, Congress mandated that not only would the healthcare industry needed to use a very specific subset and configuration of the values allowed by X12 in order to "reduce ambiguities currently permitted by the standard." ([Rule by Health and Human Services Department](https://www.federalregister.gov/documents/2011/07/08/2011-16834/administrative-simplification-adoption-of-operating-rules-for-eligibility-for-a-health-plan-and)).
As a result, the healthcare industry worked with X12 to form the X12N Insurance committee, which created a detailed specification for each transaction set. These specifications are formally called a Technical Report Type 3 (TR3). The series of TR3s produced by the X12N Insurance committee is what's commonly known as X12 HIPAA.
# Segment repetition in X12 EDI"
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/x12/segments/segment-repetition-in-x12-edi
***
title: Segment repetition in X12 EDI"
sidebarTitle: 'Segments - Repetition'
-------------------------------------
Sometimes a [segment](https://www.stedi.com/edi/x12-008010/segment) in a transaction set can be repeated. This usually shows up in implementation guides as the `Max Use` of a segment.
* `1` means that the segment cannot be repeated.
* `>1` means that the segment can be repeated an infinite number of times.
* Any other number means the segment can be repeated at most that number of times.
The X12 standard defines the repetition for each segment, but your trading partner may deviate from the standard in their implementation guide to suit their business needs. In that case, you should follow the implementation guide.
# Qualifiers
You’ll see segment repetitions most often when the segment has a qualifier. A qualifier determines the meaning of a segment. For example, the [DTM segment](https://www.stedi.com/edi/x12-008010/segment/DTM) contains a date and it uses a qualifier to tell you if it’s a shipping date, a delivery date, a blind date, etc. It often makes sense to have multiple dates, so the `DTM` segment can be repeated.
```
DTM*011*20220921~
DTM*017*20220922~
```
In the example above, the first segment is the shipping date and the second segment is the estimated delivery date.
In a situation like this, the implementation guide will often deviate from the X12 standard. The standard may say that the `DTM` segment can be repeated, say, 300 times, but if your trading partner only accepts a shipping date and an estimated delivery date, they may set a maximum of 2 repetitions.
## Multiple qualifiers
In most cases, repeated segments do not use the same qualifier more than once. After all, it wouldn’t make much sense to have a single shipment with multiple shipping dates. However, some segments have multiple qualifiers.
For example, the [MEA segment](https://www.stedi.com/edi/x12-008010/segment/MEA) represents a measurement. The first qualifier tells you what kind of measurement you’re dealing with, say a weight. The second qualifier tells you what kind of weight. The following example includes both a gross weight and a net weight.
```
MEA*WT*G*1023*LB~
MEA*WT*N*1000*LB~
```
## Repeatable qualifiers
There are also cases where it’s perfectly valid to repeat the same qualifier. For example, a container may have multiple seals. You can use a separate [REF segment](https://www.stedi.com/edi/x12-008010/segment/REF) for each seal and they’ll all have the same qualifier.
```
REF*SN*A999001~
REF*SN*A999002~
REF*SN*A999003~
```
# Long data
Every segment has a maximum character count and sometimes, you just need more characters! You’ll typically run into this situation with free-form text segments like [NTE](https://www.stedi.com/edi/x12-008010/segment/NTE) and [MSG](https://www.stedi.com/edi/x12-008010/segment/MSG). In that case, you can repeat the segment to fit more data.
```
MSG*Service Terms: The Service Terms below govern your use of the Services. Capitalized terms used in these Service Terms but not defined below are either defined i) in the Stedi Customer Agreement, or ii) in other agreements with us that govern your use of the Servic~
MSG*es (collectively, the “Agreement”). 1. Universal Service Terms (Applicable to all Services) …~
```
# Segment requirements in X12 EDI
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/x12/segments/segment-requirements-in-x12-edi
***
title: 'Segment requirements in X12 EDI'
sidebarTitle: 'Segments - Requirements'
---------------------------------------
When a segment is used in a transaction set, the X12 standard specifies two types of segment requirements: `Mandatory` and `Optional`.
* **Mandatory**: Segments marked as mandatory (`M`) must be present in the EDI transaction.
* **Optional**: Segments marked as optional (`O`) may be present in the EDI transaction.
For each transaction set, the X12 standard defines a base specification, which denotes the requirements of each segment. All segments marked as `M` (mandatory) in the base specification must be present in the EDI file sent between two trading partners. On the other hand, all segments marked as `O` (optional) in the base specification can either be optional or mandatory, depending on the implementation guide that you and your trading partner agree to.
The requirement of a segment is always defined in the context of the transaction set and the position it is used in. For example, a [REF](https://www.stedi.com/edi/x12-008010/segment/REF) segment might have different requirement parameters if it is used in an [850 Purchase Order](https://www.stedi.com/edi/x12-008010/850) vs. a [270 Eligibility, Coverage, or Benefit inquiry](https://www.stedi.com/edi/x12-008010/270). Furthermore, the same segment might be used multiple times in different places in the same transaction set. For example, a [DTM Date/Time Reference](https://www.stedi.com/edi/x12-008010/segment/DTM) segment could be optional in the `Heading` but mandatory in the `Detail`.
As with all things in X12 EDI, trading partners will create a specification to suit their business needs. For example, your trading partners may decide that some segments — even optional as per the standard — must be present in the data (i.e., are mandatory). On the other hand, according to the X12 standard, you cannot mark segments that are mandatory in the base X12 specification as optional in your guide. In practice, some businesses break the X12 standard and you’ll have to conform to their specification nonetheless.
Most X12 implementation guides used in the industry were built using a tool called SpecBuilder, which creates a standard PDF format. We will use SpecBuilder PDFs and their terminology to explain segment requirements below, but your trading partner might send these requirements in different formats (e.g. CSV, Word, custom PDF).
In these implementation guides, the segment requirements given by X12 are found in the requirement column (`Req` for short). The `Req` column will show which segments are mandatory (`M`) or optional (`O`). Trading partners that deviate from the base specification will often indicate which fields are optional or mandatory in a column called `Usage` or `Attributes`, and they typically use a different syntax, such as `Must use` (mandatory) and `Used` (optional).
Additionally, the segment requirements are also usually found on the segment detail page near the description or header. In these areas, the requirements are also indicated as either mandatory or optional. For trading partner specific requirements, look for the `User Option` or `Usage` label and the `Must use` or `Used` syntax.
## X12 types
### Mandatory
Mandatory segments are marked with an `M` or `Mandatory` in most implementation guides. If a segment is defined as mandatory in a transaction set, then you cannot send X12 data without it. In most cases, transactions that are missing mandatory segments will either be stopped by the sender, or rejected by the recipient.
For example, the [BIG (Beginning Segment for Invoice)](https://www.stedi.com/edi/x12-008010/segment/BIG) segment used in all X12 [810 Invoices](https://www.stedi.com/edi/x12-008010/810) is mandatory. It contains vital invoice information, such as the invoice number and date. You cannot send an invoice without these values.
### Optional
Optional segments are marked with an `O` or `Optional` in most implementation guides.
If a segment is marked as optional, it can be omitted in the data and the transaction would still be valid. Often, PDF specifications will explain when to use optional segments in a notes section.
For example, the [CUR (Currency)](https://www.stedi.com/edi/x12-008010/segment/CUR) segment used in X12 810 Invoices is optional. Trading partners might agree that the default currency is US Dollars and use `CUR` only when the invoice currency is different from US Dollars.
If you want to see the segment requirements for a specific transaction set, see [EDI Reference](https://www.stedi.com/edi/x12/transaction-set).
# What is a segment in X12 EDI?
Source: https://www.stedi.com/docs/edi-platform/edi-essentials/x12/segments/what-is-a-segment
***
title: 'What is a segment in X12 EDI?'
sidebarTitle: 'What is a segment?'
----------------------------------
Segments in X12 EDI contain a group of logically related [elements](https://www.stedi.com/edi/essentials/x12/elements) that are combined to communicate specific information between two trading partners. Each X12 transaction consists of segments sent in a pre-defined sequence, where each segment is separated from one another by segment terminators (e.g., `~`, `\n`, etc.). For example, here is a snippet of an [850 Purchase Order](https://www.stedi.com/edi/x12-008010/850) that contains a `BEG` and `CUR` segment.
```
BEG***00*AB*308174864**20220321~
CUR***BY*USD~
```
The X12 standard defines a list of [thousands of segments](https://www.stedi.com/edi/x12/segment), and each segment has a unique segment ID, name, description, and a set of elements that it contains. These segment attributes are fixed; they do not change, regardless of what transaction set they are sent in. Most segments appear in many transaction sets, while others are unique to individual transaction sets.
When a segment is used in a transaction set, the X12 standard provides additional attributes, such as its sequence, requirement, and repetition. These attributes are variable; they change based on which transaction set the segment is found in.
## Segment attributes
### IDs
Each segment is given a unique ID that can be two to three characters in length, and may be a combination of letters, or letters and numbers. For example, the `Party Identification` segment has the ID `N1`, the `Tax Reference` segment has the ID `TAX`, and the `Date/Time` segment has the ID `G62`. Sometimes, the segment ID is referred to as the *segment name* or *tag*.
### Names
Each segment is given a name, which is a short, generic description of what the purpose of the segment is. For example, the name of the `ACK` segment is `Line Item Acknowledgement`, the name of the `AT1` segment is `Bill of Lading Line Item Number`, and the name of the `ITA` is `Allowance, Charge or Service`. While each segment is given a name, in practice, the segment ID is used for identifying the segment, not the name.
### Descriptions
In addition to the segment name, X12 provides a longer description to explain what the segment represents and how it is used. For example, the `BEG` segment (Beginning Segment for Purchase Order) has the following description:
> To indicate the beginning of the Purchase Order Transaction Set and transmit identifying numbers and dates.
### Elements
Every segment contains one or more elements sent in a pre-defined order. Regardless of which transaction set the segment is found in, the segment always contains the same list of elements. However, depending on the element requirements of that segment and your trading partners implementation guide, some elements are considered optional.
You can read more about elements and how they are used in the [Elements in X12 EDI](https://www.stedi.com/edi/essentials/x12/elements) article.
### Sequence
For every transaction set, the X12 standard defines which segments can be sent and in what order. The order is defined by the sequence number (sometimes called position) that the segment has in the context of that transaction set.
For example, in the [180 Return Merchandise Authorization and Notification](https://www.stedi.com/edi/x12-008010/180) transaction, the `ST` segment (Transaction Set Header) is the first segment that indicates a new transaction is being sent and so it is given the 0100 position of the transaction. The `BGN` segment is next up in the sequence, and has the `0200` position. `RDR` has `0300`, `PRF` has `0400`, and so on. The position number has no semantic meaning, it is purely to indicate where a segment goes in the context of its neighbors. Even if a segment is not used or sent, the position of the following segments do not change.
Depending on the transaction set, the same segment can be used multiple times in different positions. The sequence number is useful here because it can help disambiguate which iteration of the segment a trading partner is referring to.
For example, the `DTM` (Date/Time Reference) segment is found four times in the `180` transaction; once at the `0500` position, again at the `0520` position, again at the `1300` position, and finally at the `1900` position. On the other hand, the `252` Insurance Producer Administration transaction only contains one `DTM` segment at the `0040` position.
While segment positions are useful for validation and debugging, in practice they are rarely used to describe a segment. For example, it’s rare to hear someone refer to the `DTM` as “the DTM at the 140 position.” Moreover, these positions are not always correctly calculated in the implementation guides so you shouldn’t rely on them. Instead, use the logical structure of the transaction set (e.g., heading, detail, summary, and/or loops) to explain the position.
For example, the implementation guide of the `810` invoice below defines three `REF` segments with positions `050`, `110` and `120`. So, instead of using the positions (050, 110, or 120) you can refer to them as:
* REF under the Heading
* REF in the N1 loop
* REF under detail
### Requirements
When a segment is used in a transaction set, the X12 standard specifies two types of segment requirements: mandatory or optional. In addition to the X12 requirements, trading partners will often deviate slightly from the standard to suit their business needs.
* **Mandatory**: segments marked as mandatory (`M`) must be present in the EDI transaction.
* **Optional**: segments marked as optional (`O`) may be present in the EDI transaction.
According to X12, trading partners can mark optional segments as mandatory, but they should not mark mandatory segments as optional. Additionally, while some implementation guides will mark the first segment of a loop as optional, technically all segments that are the first segment in the loop are required.
### Repetition
While some segments might be present in more than one position in a single transaction set, repetition pertains to something else. The repetition attribute determines how many time the same segment or loop can be repeated in the same position. On implementation guides, this is usually referred to as the `Max Use` of a segment.
The repetition of a segment in a transaction set can be indicated by one of the following:
* `1`, which means this segment cannot be repeated.
* Any number greater than one, which means this segment may be repeated up to, but no more than, the number indicated.
* `>1`, which means that this segment can be repeated an infinite number of times
# Aggregation functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/aggregation
***
## title: Aggregation functions
## $sum
**Signature:** `$sum(array)`
**Parameters:**
* `array` - An array of numbers.
Returns the arithmetic sum of an array of numbers. It is an error if the input array contains an item which isn't a number.
**Example**
| Expression | Result |
| ------------------- | ------ |
| `$sum([5,1,3,7,4])` | `20` |
## $max
**Signature:** `$max(array)`
**Parameters:**
* `array` - An array of numbers.
Returns the maximum number in an array of numbers. It is an error if the input array contains an item which isn't a number.
**Example**
| Expression | Result |
| ------------------- | ------ |
| `$max([5,1,3,7,4])` | `7` |
## $min
**Signature:** `$min(array)`
**Parameters:**
* `array` - An array of numbers.
Returns the minimum number in an array of numbers. It is an error if the input array contains an item which isn't a number.
**Example**
| Expression | Result |
| ------------------- | ------ |
| `$min([5,1,3,7,4])` | `1` |
## $average
**Signature:** `$average(array)`
**Parameters:**
* `array` - An array of numbers.
Returns the mean value of an array of numbers. It is an error if the input array contains an item which isn't a number.
**Example**
| Expression | Result |
| ----------------------- | ------ |
| `$average([5,1,3,7,4])` | `4` |
# Array functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/array
***
## title: Array functions
## $count
**Signature:** `$count(array)`
**Parameters:**
* `array` - An array to process.
If the `array` parameter is not an array, but rather a value of another JSON type, then the parameter is treated as a singleton array containing that value, and this function returns `1`.
Returns the number of items in the `array` parameter. If the `array` parameter is not an array, but rather a value of another JSON type, then the parameter is treated as a singleton array containing that value, and this function returns `1`.
If `array` is not specified, then the context value is used as the value of array.
**Examples**
| Expression | Result |
| ------------------- | ------ |
| `$count([1,2,3,1])` | `4` |
| `$count("hello")` | `1` |
## $append
**Signature:** `$append(array1, array2)`
**Parameters:**
* `array1` - The first array to append the second argument to.
If this parameter is not an array, then it is treated as a singleton array containing that value.
* `array2` - The second array to append to the first argument.
If this parameter is not an array, then it is treated as a singleton array containing that value.
Returns an array containing the values in `array1` followed by the values in `array2`. If either parameter is not an array, then it is treated as a singleton array containing that value.
**Examples**
| Expression | Result |
| --------------------------- | -------------------- |
| `$append([1,2,3], [4,5,6])` | `[1,2,3,4,5,6]` |
| `$append([1,2,3], 4)` | `[1,2,3,4]` |
| `$append("Hello", "World")` | `["Hello", "World"]` |
## $sort
**Signature:** `$sort(array, [, function])`
**Parameters:**
* `array` - An array to sort.
* `function` - If a comparator `function` is supplied, then is must be a function that takes two parameters:
`function(left, right)`
This function gets invoked by the sorting algorithm to compare two values `left` and `right`. If the value of left should be placed after the value of `right` in the desired sort order, then the function must return Boolean `true` to indicate a swap. Otherwise it must return `false`.
Returns an array containing all the values in the `array` parameter, but sorted into order. If no `function` parameter is supplied, then the `array` parameter must contain only numbers or only strings, and they will be sorted in order of increasing number, or increasing unicode codepoint respectively.
If a comparator `function` is supplied, then is must be a function that takes two parameters:
`function(left, right)`
This function gets invoked by the sorting algorithm to compare two values `left` and `right`. If the value of left should be placed after the value of `right` in the desired sort order, then the function must return Boolean `true` to indicate a swap. Otherwise it must return `false`.
**Example**
```
$sort(Account.Order.Product, function($l, $r) {
$l.Description.Weight > $r.Description.Weight
})
```
This sorts the products in order of increasing weight.
The sorting algorithm is stable which means that values within the original array which are the same according to the comparator function will remain in the original order in the sorted array.
## $reverse
**Signature:** `$reverse(array)`
**Parameters:**
* `array` - An array to reverse.
Returns an array containing all the values from the `array` parameter, but in reverse order.
**Examples**
| Expression | Result |
| ------------------------------ | -------------------- |
| `$reverse(["Hello", "World"])` | `["World", "Hello"]` |
| `[1..5] ~> $reverse()` | `[5, 4, 3, 2, 1]` |
## $shuffle
**Signature:** `$shuffle(array)`
**Parameters:**
* `array` - An array to shuffle.
Returns an array containing all the values from the `array` parameter, but shuffled into random order.
**Examples**
| Expression | Result |
| ------------------ | ----------------------------- |
| `$shuffle([1..9])` | `[6, 8, 2, 3, 9, 5, 1, 4, 7]` |
## $distinct
**Signature:** `$distinct(array)`
**Parameters:**
* `array` - An array to process.
Returns an array containing all the values from the `array` parameter, but with any duplicates removed. Values are tested for deep equality as if by using the [equality operator](https://docs.jsonata.org/comparison-operators#equals).
**Examples**
| Expression | Result |
| ----------------------------------------------------- | ------------------------------- |
| `$distinct([1,2,3,3,4,3,5])` | `[1, 2, 3, 4, 5]` |
| `$distinct(Account.Order.Product.Description.Colour)` | `["Purple", "Orange", "Black"]` |
## $zip
**Signature:** `$zip(array1, ...)`
**Parameters:**
* `array1` - An array to zip.
Returns a convolved (zipped) array containing grouped arrays of values from the `array1` ... `arrayN` arguments from index 0, 1, 2, etc.
This function accepts a variable number of arguments. The length of the returned array is equal to the length of the shortest array in the arguments.
**Examples**
| Expression | Result |
| ----------------------------- | ----------------------- |
| `$zip([1,2,3], [4,5,6])` | `[[1,4] ,[2,5], [3,6]]` |
| `$zip([1,2,3],[4,5],[7,8,9])` | `[[1,4,7], [2,5,8]]` |
# Boolean functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/boolean
***
## title: Boolean functions
## $boolean
**Signature:** `$boolean(arg)`
**Parameters:**
* `arg` - An argument to be cast to a Boolean.
Casts the argument to a Boolean using the following rules:
| Argument type | Result |
| --------------------------------------------- | --------- |
| Boolean | unchanged |
| string: empty | `false` |
| string: non-empty | `true` |
| number: 0 | `false` |
| number: non-zero | `true` |
| null | `false` |
| array: empty | `false` |
| array: contains a member that casts to `true` | `true` |
| array: all members cast to `false` | `false` |
| object: empty | `false` |
| object: non-empty | `true` |
| function | `false` |
## $not
**Signature:** `$not(arg)`
**Parameters:**
* `arg` - An argument to be cast to a Boolean and inverted.
Returns Boolean NOT on the argument. `arg` is first cast to a boolean.
## $exists
**Signature:** `$exists(arg)`
**Parameters:**
* `arg` - An argument to chech the existence of.
Returns Boolean `true` if the arg expression evaluates to a value, or `false` if the expression does not match anything (e.g. a path to a non-existent field reference).
# Date/time functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/date-time
***
## title: Date/time functions
## $now
**Signature:** `$now([picture [, timezone]])`
**Parameters:**
* `picture` - If the optional `picture` string is supplied, then the timestamp is formatted occording to the representation specified in that string.
The behaviour of this function is consistent with the two-argument version of the XPath/XQuery function [fn:format-dateTime](https://www.w3.org/TR/xpath-functions-31/#func-format-dateTime) as defined in the XPath F\&O 3.1 specification. The picture string parameter defines how the timestamp is formatted and has the [same syntax](https://www.w3.org/TR/xpath-functions-31/#date-picture-string) as fn:format-dateTime.
* `timezone` - If the optional `timezone` string is supplied, then the formatted timestamp will be in that timezone.
The `timezone` string should be in the format "±HHMM", where ± is either the plus or minus sign and HHMM is the offset in hours and minutes from UTC. Positive offset for timezones east of UTC, negative offset for timezones west of UTC.
Generates a UTC timestamp in ISO 8601 compatible format and returns it as a string. All invocations of `$now()` within an evaluation of an expression will all return the same timestamp value.
If the optional `picture` and `timezone` parameters are supplied, then the current timestamp is formatted as described by the [`$fromMillis()`](/edi-platform/mappings/jsonata/jsonata-functions/date-time#frommillis) function.
**Examples**
| Expression | Result |
| ---------- | ---------------------------- |
| `$now()` | `"2017-05-15T15:12:59.152Z"` |
## $millis
**Signature:** `$millis()`
Returns the number of milliseconds since the Unix *Epoch* (1 January, 1970 UTC) as a number. All invocations of `$millis()` within an evaluation of an expression will all return the same value.
**Examples**
| Expression | Result |
| ----------- | --------------- |
| `$millis()` | `1502700297574` |
## $fromMillis
**Signature:** `$fromMillis(number [, picture [, timezone]])`
**Parameters:**
* `number` - A number representing milliseconds since the Unix *Epoch* (1 January, 1970 UTC).
* `picture` - If the optional `picture` string is supplied, then the timestamp is formatted according to the representation specified in that string.
The behavior of this function is consistent with the two-argument version of the XPath/XQuery function [fn:format-dateTime](https://www.w3.org/TR/xpath-functions-31/#func-format-dateTime) as defined in the XPath F\&O 3.1 specification. The picture string parameter defines how the timestamp is formatted and has the [same syntax](https://www.w3.org/TR/xpath-functions-31/#date-picture-string) as fn:format-dateTime.
* `timezone` - If the optional `timezone` string is supplied, then the formatted timestamp will be in that timezone.
The `timezone` string should be in the format "±HHMM", where ± is either the plus or minus sign and HHMM is the offset in hours and minutes from UTC. Positive offset for timezones east of UTC, negative offset for timezones west of UTC.
Convert the `number` representing milliseconds since the Unix *Epoch* (1 January, 1970 UTC) to a formatted string representation of the timestamp as specified by the `picture` string.
If the optional `picture` parameter is omitted, then the timestamp is formatted in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format.
If the optional `picture` string is supplied, then the timestamp is formatted according to the representation specified in that string.
The behavior of this function is consistent with the two-argument version of the XPath/XQuery function [fn:format-dateTime](https://www.w3.org/TR/xpath-functions-31/#func-format-dateTime) as defined in the XPath F\&O 3.1 specification. The picture string parameter defines how the timestamp is formatted and has the [same syntax](https://www.w3.org/TR/xpath-functions-31/#date-picture-string) as fn:format-dateTime.
If the optional `timezone` string is supplied, then the formatted timestamp will be in that timezone. The `timezone` string should be in the
format "±HHMM", where ± is either the plus or minus sign and HHMM is the offset in hours and minutes from UTC. Positive offset for timezones
east of UTC, negative offset for timezones west of UTC.
**Examples**
| Expression | Result |
| ------------------------------------------------------------------ | ---------------------------- |
| `$fromMillis(1510067557121)` | `"2017-11-07T15:12:37.121Z"` |
| `$fromMillis(1510067557121, '[M01]/[D01]/[Y0001] [h#1]:[m01][P]')` | `"11/07/2017 3:12pm"` |
| `$fromMillis(1510067557121, '[H01]:[m01]:[s01] [z]', '-0500')` | `"10:12:37 GMT-05:00"` |
## $toMillis
**Signature:** `$toMillis(timestamp [, picture])`
**Parameters:**
* `timestamp` - A formatted timestamp string.
If the optional `picture` string is not specified, then the format of the timestamp is assumed to be [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html). An error is thrown if the string is not in the correct format.
* `picture` - If the `picture` string is specified, then the format is assumed to be described by this picture string using the [same syntax](https://www.w3.org/TR/xpath-functions-31/#date-picture-string) as the XPath/XQuery function [fn:format-dateTime](https://www.w3.org/TR/xpath-functions-31/#func-format-dateTime), defined in the XPath F\&O 3.1 specification.
Convert a `timestamp` string to the number of milliseconds since the Unix *Epoch* (1 January, 1970 UTC) as a number. This function is provided by Stedi and isn't a part of the JSONata standard library.
If the optional `picture` string is not specified, then the format of the timestamp is assumed to be [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html). An error is thrown if the string is not in the correct format.
If the `picture` string is specified, then the format is assumed to be described by this picture string using the [same syntax](https://www.w3.org/TR/xpath-functions-31/#date-picture-string) as the XPath/XQuery function [fn:format-dateTime](https://www.w3.org/TR/xpath-functions-31/#func-format-dateTime), defined in the XPath F\&O 3.1 specification.
**Examples**
| Expression | Result |
| --------------------------------------- | --------------- |
| `$toMillis("2017-11-07T15:07:54.972Z")` | `1510067274972` |
## $convertDateTime
**Signature:** `$convertDateTime(str, sourceFormat, targetFormat [, sourceTimezone [, targetTimezone]])`
**Parameters:**
* `str` - An input string with date to be formatted
* `sourceFormat` - Date format of the input string using [using unicode tokens](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)
* `targetFormat` - Format of the output string using [using unicode tokens](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)
* `sourceTimezone` - Specifies source date's timezone if the date is in format without the zone offset e.g.: +01:00 or Z
* `targetTimezone` - If specified, function will also convert date's timezone to the targeted one.
Parses the `str` according to the `sourceFormat` and returns a formatted string according to `targetFormat`.
If `targetTimezone` is specified, function will also convert date's timezone to desired one. If `str` is in format without timezone defined, please use `sourceTimezone` to specify its timezone. Without it being specified, function will assume UTC timezone. If both `str` and `sourceTimezone` will be specified, zone offset in `str` will take a precedence over `sourceTimezone`.
Both formats must be specified [using unicode tokens](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table).
This function is provided by Stedi and isn't a part of the JSONata standard library.
Note there are 4 tokens that might cause confusion:
* `D` and `DD` that represent the day of a year (1, 2, ..., 365, 366) are often confused with `d` and `dd` that represent the day of a month (1, 2, ..., 31).
* `y` and `yyyy` that represent the local week-numbering year (44, 01, 00, 17) are often confused with `yy` and `yyyy` that represent the calendar year.
On top of the `$convertDateTime` function, we also provide popular date/time formats as constants under `$dateTime` object:
| Variable | Value |
| ------------------------- | -------------------------------- |
| `$dateTime.RFC3339` | `"yyyy-MM-dd'T'HH:mm:ssXXX"` |
| `$dateTime.RFC3339Millis` | `"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"` |
| `$dateTime.EDIDate` | `"yyMMdd"` |
| `$dateTime.EDIDateLong` | `"yyyyMMdd"` |
**Example**
| Function call | Returned value |
| ----------------------------------------------------------------------------------------------------------- | ----------------------------- |
| `$convertDateTime("20140919", "yyyyMMdd", "yyyy-MM-dd")` | `"2014-09-19"` |
| `$convertDateTime("2021-01-02T12:00:00Z", $dateTime.RFC3339, "yyyy-MM-dd")` | `"2021-01-02"` |
| `$convertDateTime("2021-01-02T12:00:00+00:00", $dateTime.RFC3339, "yyyy-MM-dd")` | `"2021-01-02"` |
| `$convertDateTime("210102", $dateTime.EDIDate, $dateTime.RFC3339`) | `"2021-01-02T12:00:00Z"` |
| `$convertDateTime("15:00 2nd January 2021", "HH:mm do MMMM yyyy", "yyyy-MM-dd")` | `"2021-01-02"` |
| `$convertDateTime("2021-01-01T01:00:00-11:00", $dateTime.RFC3339, $dateTime.RFC3339, null, "UTC")` | `"2021-01-01T12:00:00Z"` |
| `$convertDateTime("2021-01-01T01:00:00Z", $dateTime.RFC3339, $dateTime.RFC3339, null, "Asia/Bangkok")` | `"2021-01-01T08:00:00+07:00"` |
| `$convertDateTime("2021-01-01T01:00:00Z", $dateTime.RFC3339, $dateTime.RFC3339, "UTC", "America/New_York")` | `"2020-12-31T20:00:00-05:00"` |
| `$convertDateTime("2021-01-01T01:00:00", "yyyy-MM-dd'T'HH:mm:ss", $dateTime.RFC3339, "EST", "UTC")` | `"2021-01-01T06:00:00Z"` |
## $currentDateTime
**Signature:** `$currentDateTime(format [, timezone])`
**Parameters:**
* `format` - Date format of the input string using [using unicode tokens](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)
* `timezone` - Optional, specifies the timezone in which the date/time is generated. Defaults to UTC.
Returns a current date and time formatted string according to `format`. Format must be specified [using unicode tokens](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table).
Optionally, a timezone can be specified. If not specified, the timezone is assumed to be UTC.
This function is provided by Stedi and isn't a part of the JSONata standard library.
Note there are 4 tokens that might cause confusion:
* `D` and `DD` that represent the day of a year (1, 2, ..., 365, 366) are often confused with `d` and `dd` that represent the day of a month (1, 2, ..., 31).
* `y` and `yyyy` that represent the local week-numbering year (44, 01, 00, 17) are often confused with `yy` and `yyyy` that represent the calendar year.
On top of the `$currentDateTime` function, we also provide popular date/time formats as constants under `$dateTime` object:
| Variable | Value |
| ------------------------- | -------------------------------- |
| `$dateTime.RFC3339` | `"yyyy-MM-dd'T'HH:mm:ssXXX"` |
| `$dateTime.RFC3339Millis` | `"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"` |
| `$dateTime.EDIDate` | `"yyMMdd"` |
| `$dateTime.EDIDateLong` | `"yyyyMMdd"` |
**Example**
| Function call | Returned value |
| ------------------------------------------- | ---------------------------- |
| `$currentDateTime("yyyy-MM-dd")` | `"2022-02-09"` |
| `$currentDateTime($dateTime.EDIDate)` | `"220209"` |
| `$currentDateTime($dateTime.RFC3339Millis)` | `"2022-02-09T08:23:52.000Z"` |
| `$currentDateTime("yyyy-MM-dd", "EST")` | `"2022-02-09"` |
# Higher order functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/higher-order
***
## title: Higher order functions
## $map
**Signature:** `$map(array, function)`
**Parameters:**
* `array` - An array to map from.
* `function` - The function that is supplied as the second parameter must have the following signature:
`function(value [, index [, array]])`
Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.
Returns an array containing the results of applying the `function` parameter to each value in the `array` parameter.
The function that is supplied as the second parameter must have the following signature:
`function(value [, index [, array]])`
Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.
**Examples**
| Expression | Result |
| ----------------------- | --------------------------- |
| `$map([1..5], $string)` | `["1", "2", "3", "4", "5"]` |
With user-defined (lambda) function:
```
$map(Email.address, function($v, $i, $a) {
'Item ' & ($i+1) & ' of ' & $count($a) & ': ' & $v
})
```
evaluates to:
```
[
"Item 1 of 4: fred.smith@my-work.com",
"Item 2 of 4: fsmith@my-work.com",
"Item 3 of 4: freddy@my-social.com",
"Item 4 of 4: frederic.smith@very-serious.com"
]
```
## $filter
**Signature:** `$filter(array, function)`
**Parameters:**
* `array` - An array to filter.
* `function` - The function that is supplied as the second parameter must have the following signature:
`function(value [, index [, array]])`
Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.
Returns an array containing only the values in the `array` parameter that satisfy the `function` predicate (i.e. `function` returns Boolean `true` when passed the value).
The function that is supplied as the second parameter must have the following signature:
`function(value [, index [, array]])`
Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.
**Example** The following expression returns all the products whose price is higher than average:
```
$filter(Account.Order.Product, function($v, $i, $a) {
$v.Price > $average($a.Price)
})
```
## $single
**Signature:** `$single(array, function)`
**Parameters:**
* `array` - An array to search in.
* `function` - The function that is supplied as the second parameter must have the following signature:
`function(value [, index [, array]])`
Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.
Returns the one and only one value in the `array` parameter that satisfy the `function` predicate (i.e. `function` returns Boolean `true` when passed the value). Throws an exception if the number of matching values is not exactly one.
The function that is supplied as the second parameter must have the following signature:
`function(value [, index [, array]])`
Each value in the input array is passed in as the first parameter in the supplied function. The index (position) of that value in the input array is passed in as the second parameter, if specified. The whole input array is passed in as the third parameter, if specified.
**Example** The following expression the product in the order whose SKU is `"0406654608"`:
```
$single(Account.Order.Product, function($v, $i, $a) {
$v.SKU = "0406654608"
})
```
## $reduce
**Signature:** `$reduce(array, function [, init])`
**Parameters:**
* `array` - An array to reduce.
* `function` - The `function` must accept at least two arguments, and behaves like an infix operator between each value within the `array`. The signature of this supplied function must be of the form:
`function(accumulator, value[, index[, array]])`
Returns an aggregated value derived from applying the `function` parameter successively to each value in `array` in combination with the result of the previous application of the function.
The `function` must accept at least two arguments, and behaves like an infix operator between each value within the `array`. The signature of this supplied function must be of the form:
`myfunc($accumulator, $value[, $index[, $array]])`
**Example**
```
(
$product := function($i, $j){$i * $j};
$reduce([1..5], $product)
)
```
This multiplies all the values together in the array `[1..5]` to return `120`.
If the optional `init` parameter is supplied, then that value is used as the initial value in the aggregation (fold) process. If not supplied, the initial value is the first value in the `array` parameter.
## $sift
**Signature:** `$sift(object, function)`
**Parameters:**
* `object` - An object to process.
* `function` - The `function` that is supplied as the second parameter must have the following signature:
`function(value [, key [, object]])`
Each value in the input object is passed in as the first parameter in the supplied function. The key (property name) of that value in the input object is passed in as the second parameter, if specified. The whole input object is passed in as the third parameter, if specified.
Returns an object that contains only the key/value pairs from the `object` parameter that satisfy the predicate `function` passed in as the second parameter.
If `object` is not specified, then the context value is used as the value of `object`. It is an error if `object` is not an object.
The function that is supplied as the second parameter must have the following signature:
`function(value [, key [, object]])`
Each value in the input object is passed in as the first parameter in the supplied function. The key (property name) of that value in the input object is passed in as the second parameter, if specified. The whole input object is passed in as the third parameter, if specified.
**Example**
```
Account.Order.Product.$sift(function($v, $k) {$k ~> /^Product/})
```
This sifts each of the Product objects such that they only contain the fields whose keys start with the string "Product" (using a regex). This example returns:
```
[
{
"Product Name": "Bowler Hat",
"ProductID": 858383
},
{
"Product Name": "Trilby hat",
"ProductID": 858236
},
{
"Product Name": "Bowler Hat",
"ProductID": 858383
},
{
"ProductID": 345664,
"Product Name": "Cloak"
}
]
```
# JSONata Functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions
***
## title: JSONata Functions
Get started quickly with JSONata for mapping expressions. Automate complex
data transformations without a mess of lines and arrows.
* [String functions](/edi-platform/mappings/jsonata/jsonata-functions/string)
* [Numeric functions](/edi-platform/mappings/jsonata/jsonata-functions/numeric)
* [Aggregation functions](/edi-platform/mappings/jsonata/jsonata-functions/aggregation)
* [Boolean functions](/edi-platform/mappings/jsonata/jsonata-functions/boolean)
* [Array functions](/edi-platform/mappings/jsonata/jsonata-functions/array)
* [Object functions](/edi-platform/mappings/jsonata/jsonata-functions/object)
* [Date/time functions](/edi-platform/mappings/jsonata/jsonata-functions/date-time)
* [Higher order functions](/edi-platform/mappings/jsonata/jsonata-functions/higher-order)
* [Other functions](/edi-platform/mappings/jsonata/jsonata-functions/other)
# Numeric functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/numeric
***
## title: Numeric functions
It is not recommended to use JSONata for floating point arithmetic, such as
financial calculations. Floating-point arithmetic can introduce rounding
errors, which can accumulate and lead to incorrect results. Visit our [JSONata
Playground](https://stedi.link/UKXfsxe) for an example. We recommend
representing monetary values as integers (e.g. cents) and performing
calculations on those integers.
## $number
**Signature:** `$number(arg)`
**Parameters:**
* `arg` - An argument to be cast to number.
Casts the `arg` parameter to a number using the following casting rules
* Numbers are unchanged
* Strings that contain a sequence of characters that represent a legal JSON number are converted to that number
* Hexadecimal numbers start with `0x`, Octal numbers with `0o`, binary numbers with `0b`
* Boolean `true` casts to `1`, Boolean `false` casts to `0`
If `arg` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `arg`.
**Examples**
| Expression | Result |
| ------------------------------------- | ----------------- |
| `$number("5")` | `5` |
| `$number("0x12")` | `0x18` |
| `["1", "2", "3", "4", "5"].$number()` | `[1, 2, 3, 4, 5]` |
## $abs
**Signature:** `$abs(number)`
**Parameters:**
* `number` - A number to get an absolute value of.
Returns the absolute value of the `number` parameter, i.e. if the number is negative, it returns the positive value.
If `number` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `number`.
**Examples**
| Expression | Result |
| ---------- | ------ |
| `$abs(5)` | `5` |
| `$abs(-5)` | `5` |
## $floor
**Signature:** `$floor(number)`
**Parameters:**
* `number` - The source number.
Returns the value of `number` rounded down to the nearest integer that is smaller or equal to `number`.
If `number` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `number`.
**Examples**
| Expression | Result |
| -------------- | ------ |
| `$floor(5)` | `5` |
| `$floor(5.3)` | `5` |
| `$floor(5.8)` | `5` |
| `$floor(-5.3)` | `-6` |
## $ceil
**Signature:** `$ceil(number)`
**Parameters:**
* `number` - The source number.
Returns the value of `number` rounded up to the nearest integer that is greater than or equal to `number`.
If `number` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `number`.
**Examples**
| Expression | Result |
| ------------- | ------ |
| `$ceil(5)` | `5` |
| `$ceil(5.3)` | `6` |
| `$ceil(5.8)` | `6` |
| `$ceil(-5.3)` | `-5` |
## $round
**Signature:** `$round(number [, precision])`
**Parameters:**
* `number` - The source number.
* `precision` - The `precision` parameter (which must be an integer) species the number of decimal places to be present in the rounded number.
If `precision` is not specified then it defaults to the value `0` and the number is rounded to the nearest integer.
If `precision` is negative, then its value specifies which column to round to on the left side of the decimal place
Returns the value of the `number` parameter rounded to the number of decimal places specified by the optional `precision` parameter.
The `precision` parameter (which must be an integer) species the number of decimal places to be present in the rounded number. If `precision` is not specified then it defaults to the value `0` and the number is rounded to the nearest integer. If `precision` is negative, then its value specifies which column to round to on the left side of the decimal place
This function uses the [Round half to even](https://en.wikipedia.org/wiki/Rounding#Round_half_to_even) strategy to decide which way to round numbers that fall exactly between two candidates at the specified precision. This strategy is commonly used in financial calculations and is the default rounding mode in IEEE 754.
**Examples**
| Expression | Result |
| --------------------- | -------- |
| `$round(123.456)` | `123` |
| `$round(123.456, 2)` | `123.46` |
| `$round(123.456, -1)` | `120` |
| `$round(123.456, -2)` | `100` |
| `$round(11.5)` | `12` |
| `$round(12.5)` | `12` |
| `$round(125, -1)` | `120` |
## $power
**Signature:** `$power(base, exponent)`
**Parameters:**
* `base` - The base number (`baseexponent`).
* `exponent` - The exponent number (`baseexponent`).
Returns the value of `base` raised to the power of `exponent` (`baseexponent`).
If `base` is not specified (i.e. this function is invoked with one argument), then the context value is used as the value of `base`.
An error is thrown if the values of `base` and `exponent` lead to a value that cannot be represented as a JSON number (e.g. Infinity, complex numbers).
**Examples**
| Expression | Result |
| ---------------- | ---------------- |
| `$power(2, 8)` | `256` |
| `$power(2, 0.5)` | `1.414213562373` |
| `$power(2, -2)` | `0.25` |
## $sqrt
**Signature:** `$sqrt(number)`
**Parameters:**
* `number` - The source number.
Returns the square root of the value of the `number` parameter.
If `number` is not specified (i.e. this function is invoked with one argument), then the context value is used as the value of `number`.
**Examples**
| Expression | Result |
| ---------- | ---------------- |
| `$sqrt(4)` | `2` |
| `$sqrt(2)` | `1.414213562373` |
## $random
**Signature:** `$random()`
Returns a pseudo random number greater than or equal to zero and less than one `(0 ≤ n < 1)`
**Examples**
| Expression | Result |
| ----------- | ----------------- |
| `$random()` | `0.7973541067127` |
| `$random()` | `0.414213562373` |
| `$random()` | `0.6558078550072` |
## $formatNumber
**Signature:** `$formatNumber(number, picture [, options])`
**Parameters:**
* `number` - The source number.
* `picture` - Format of the desired decimal representation.
The picture string parameter defines how the number is formatted and has the [same syntax](https://www.w3.org/TR/xpath-functions-31/#syntax-of-picture-string) as fn:format-number.
* `options` - The optional third argument `options` is used to override the default locale specific formatting characters such as the decimal separator.
If supplied, this argument must be an object containing name/value pairs specified in the [decimal format](https://www.w3.org/TR/xpath-functions-31/#defining-decimal-format) section of the XPath F\&O 3.1 specification.
Casts the `number` to a string and formats it to a decimal representation as specified by the `picture` string.
The behaviour of this function is consistent with the XPath/XQuery function [fn:format-number](https://www.w3.org/TR/xpath-functions-31/#func-format-number) as defined in the XPath F\&O 3.1 specification. The picture string parameter defines how the number is formatted and has the [same syntax](https://www.w3.org/TR/xpath-functions-31/#syntax-of-picture-string) as fn:format-number.
The optional third argument `options` is used to override the default locale specific formatting characters such as the decimal separator. If supplied, this argument must be an object containing name/value pairs specified in the [decimal format](https://www.w3.org/TR/xpath-functions-31/#defining-decimal-format) section of the XPath F\&O 3.1 specification.
**Examples**
| Expression | Result |
| ----------------------------------------- | ------------- |
| `$formatNumber(12345.6, '#,###.00')` | `"12,345.60"` |
| `$formatNumber(1234.5678, "00.000e0")` | `"12.346e2"` |
| `$formatNumber(34.555, "#0.00;(#0.00)")` | `"34.56"` |
| `$formatNumber(-34.555, "#0.00;(#0.00)")` | `"(34.56)"` |
## $formatBase
**Signature:** `$formatBase(number [, radix])`
**Parameters:**
* `number` - The source number.
* `radix` - The optional `radix` parameter represents the mathematical base of the `number`.
If `radix` is not specified, then it defaults to base 10. `radix` can be between 2 and 36, otherwise an error is thrown.
Casts the `number` to a string and formats it to an integer represented in the number base specified by the `radix` argument. If `radix` is not specified, then it defaults to base 10. `radix` can be between 2 and 36, otherwise an error is thrown.
**Examples**
| Expression | Result |
| ----------------------- | ----------- |
| `$formatBase(100, 2)` | `"1100100"` |
| `$formatBase(2555, 16)` | `"9fb"` |
## $formatInteger
**Signature:** `$formatInteger(number, picture)`
**Parameters:**
* `number` - The source number.
* `picture` - Format of the desired integer representation.
The picture string parameter defines how the number is formatted and has the [same syntax](https://www.w3.org/TR/xpath-functions-31/#func-format-integer) as fn:format-integer.
Casts the `number` to a string and formats it to an integer representation as specified by the `picture` string.
The behaviour of this function is consistent with the two-argument version of the XPath/XQuery function [fn:format-integer](https://www.w3.org/TR/xpath-functions-31/#func-format-integer) as defined in the XPath F\&O 3.1 specification. The picture string parameter defines how the number is formatted and has the same syntax as fn:format-integer.
**Examples**
| Expression | Result |
| --------------------------- | ----------------------------------------------- |
| `$formatInteger(2789, 'w')` | `"two thousand, seven hundred and eighty-nine"` |
| `$formatInteger(1999, 'I')` | `"MCMXCIX"` |
## $parseInteger
**Signature:** `$parseInteger(string, picture)`
**Parameters:**
* `string` - The source string to parse.
* `picture` - Format of the integer representation.
The picture string parameter has the same format as `$formatInteger`, which has the [same syntax](https://www.w3.org/TR/xpath-functions-31/#func-format-integer) as fn:format-integer.
Parses the contents of the `string` parameter to an integer (as a JSON number) using the format specified by the `picture` string.
The picture string parameter has the same format as `$formatInteger`. Although the XPath specification does not have an equivalent
function for parsing integers, this capability has been added to JSONata.
**Examples**
| Expression | Result |
| --------------------------------------------------------------------- | ---------- |
| `$parseInteger("twelve thousand, four hundred and seventy-six", 'w')` | `12476` |
| `$parseInteger('12,345,678', '#,##0')` | `12345678` |
# Object functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/object
***
## title: Object functions
## $keys
**Signature:** `$keys(object)`
**Parameters:**
* `object` - The source object to get the keys from.
Returns an array containing the keys in the object. If the argument is an array of objects, then the array returned contains a de-duplicated list of all the keys in all of the objects.
## $lookup
**Signature:** `$lookup(object, key)`
**Parameters:**
* `object` - An object to search for a `key` in.
If the `object` argument is an array of objects, then all of the objects in the array are searched
* `key` - A key to search for.
Returns the value associated with `key` in `object`. If the first argument is an array of objects, then all of the objects in the array are searched, and the values associated with all occurrences of `key` are returned.
## $spread
**Signature:** `$spread(object)`
**Parameters:**
* `object` - An object to convert.
If the `object` parameter is an array of objects, then the resultant array contains an object for every key/value pair in every object in the supplied array.
Splits an object containing key/value pairs into an array of objects, each of which has a single key/value pair from the input object. If the parameter is an array of objects, then the resultant array contains an object for every key/value pair in every object in the supplied array.
## $merge
**Signature:** `$merge(object1, ...)`
**Parameters:**
* `object1` - An object to merge.
Merges an array of objects into a single object containing all the key/value pairs from each of the objects in the input array. If any of the input objects contain the same key, then the returned object will contain the value of the last one in the array. It is an error if the input array contains an item that is not an object.
## $each
**Signature:** `$each(object, function)`
**Parameters:**
* `object` - An object to process.
* `function` - The `function` parameter will get invoked with two arguments:
`function(value, name)`
where the `value` parameter is the value of each name/value pair in the object and `name` is its name. The `name` parameter is optional.
Returns an array containing the values return by the `function` when applied to each key/value pair in the `object`.
The `function` parameter will get invoked with two arguments:
`function(value, name)`
where the `value` parameter is the value of each name/value pair in the object and `name` is its name. The `name` parameter is optional.
| Expression | Result |
| ------------------------------------------------------- | -------------------------------------------------------------------- |
| `{'$each(Address, function($v, $k) {$k & ": " & $v})'}` | `["Street: Hursley Park", "City: Winchester", "Postcode: SO21 2JN"]` |
## $error
**Signature:** `$error(message)`
**Parameters:**
* `message` - An error message to throw.
Deliberately throws an error with an optional `message`
## $assert
**Signature:** `$assert(condition, message)`
**Parameters:**
* `condition` - A condition expression to assert.
* `message` - An error message to throw on `condition` assertion failure
If `condition` is true, the function returns undefined. If the condition is false, an exception is thrown with the `message` as the message of the exception.
## $type
**Signature:** `$type(value)`
**Parameters:**
* `value` - A value to get the type of.
Evaluates the type of `value` and returns one of the following strings:
* `"null"`
* `"number"`
* `"string"`
* `"boolean"`
* `"array"`
* `"object"`
* `"function"` Returns (non-string) `undefined` when `value` is `undefined`.
# Other functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/other
***
## title: Other functions
## $lookupTable
**Signature:** `$lookupTable(table, filterKeys, filterPredicates[, options])`
**Parameters:**
* `table` - Source lookup table. All lookup tables are available inside $tables global variable
* `filterKeys` - String or array of strings of keys to filter on
* `filterPredicates` - One or more predicates to filter on. If `filterKeys` is an array, `filterPredicates` must be an array of the same length
* `options` - Object with optional properties:
* `wildcard` - Wildcard string to use for matching. E.g. if set to "\*", then "express\_aero" will match "express\_\*".
Returns row from a lookup table where all filter conditions are satisfied.
Supports [wildcard matching](/edi-platform/mappings/jsonata/common-mapping-expressions#lookup-table-wildcards).
This function is provided by Stedi and isn't a part of the JSONata standard library.
**Example**
Given following lookup table named "shipping":
| Key | Value | Preferred |
| --- | ----------- | --------- |
| 1 | express | false |
| 2 | standard | false |
| 2 | overnight | true |
| 3 | express\_\* | false |
| Expression | Result |
| ---------------------------------------------------------------------------------------- | ------------------- |
| `{'$lookupTable($tables.shipping, "Key", "1").Value'}` | `"express"` |
| `{'$lookupTable($tables.shipping, "Key", "2").Preferred'}` | `["false", "true"]` |
| `{'$lookupTable($tables.shipping, ["Key", "Preferred"], ["2", "true"]).Value'}` | `"overnight"` |
| `{'$lookupTable($tables.shipping, "Value", "express_aero", { "wildcard": "\*" }).Key'}` | `"3"` |
| `{'$lookupTable($tables.shipping, "Value", "express_other", { "wildcard": "\*" }).Key'}` | `"3"` |
## $uuid
**Signature:** `$uuid()`
Create a version 4 (random) UUID.
This function is provided by Stedi and isn't a part of the JSONata standard library.
**Example**
| Expression | Result |
| ---------- | ---------------------------------------- |
| `$uuid()` | `"1a28e35f-d420-4b95-ad09-1bb4b39821dc"` |
# String functions
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-functions/string
***
## title: String functions
## $string
**Signature:** `$string(arg, prettify)`
**Parameters:**
* `arg` - An argument to be cast to string.
* `prettify` - If `prettify` is true, then "prettified" JSON is produced. i.e one line per field and lines will be indented based on the field depth.
Casts the arg parameter to a string.
If `arg` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `arg`.
If `prettify` is true, then "prettified" JSON is produced. i.e one line per field and lines will be indented based on the field depth.
**Examples**
| Expression | Result |
| ------------------ | --------------------------- |
| `$string(5)` | `"5"` |
| `[1..5].$string()` | `["1", "2", "3", "4", "5"]` |
## $length
**Signature:** `$length(str)`
**Parameters:**
* `str` - A string to get the length of.
An error is thrown if `str` is not a string.
Returns the number of characters in the string `str`.
If `str` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `str`.
An error is thrown if `str` is not a string.
**Examples**
| Expression | Result |
| ------------------------ | ------ |
| `$length("Hello World")` | `11` |
## $substring
**Signature:** `$substring(str, start[, length])`
**Parameters:**
* `str` - The source string.
* `start` - The index of the first character to include in the returned substring.
If start is negative then it indicates the number of characters from the end of `str`.
* `length` - If length is specified, then the substring will contain maximum length characters.
Returns a string containing the characters in the first parameter `str` starting at position start (zero-offset). If `str` is not specified (i.e. this function is invoked with only the numeric argument(s)), then the context value is used as the value of `str`.
If length is specified, then the substring will contain maximum length characters.
If start is negative then it indicates the number of characters from the end of `str`.
**Examples**
| Expression | Result |
| ---------------------------------- | ------------ |
| `$substring("Hello World", 3)` | `"lo World"` |
| `$substring("Hello World", 3, 5)` | `"lo Wo"` |
| `$substring("Hello World", -4)` | `"orld"` |
| `$substring("Hello World", -4, 2)` | `"or"` |
## $substringBefore
**Signature:** `$substringBefore(str, chars)`
**Parameters:**
* `str` - The source string.
* `chars` - A character sequence to search for within the `str`.
If `str` does not contain `chars`, then this function returns `str`.
Returns the substring before the first occurrence of the character sequence `chars` in `str`.
If `str` is not specified (i.e. this function is invoked with only one argument), then the context value is used as the value of `str`.
If `str` does not contain `chars`, then it returns `str`.
**Examples**
| Expression | Result |
| -------------------------------------- | --------- |
| `$substringBefore("Hello World", " ")` | `"Hello"` |
## $substringAfter
**Signature:** `$substringAfter(str, chars)`
**Parameters:**
* `str` - The source string.
* `chars` - A character sequence to search for within the `str`.
If `str` does not contain `chars`, then this function returns `str`.
Returns the substring after the first occurrence of the character sequence `chars` in `str`.
If `str` is not specified (i.e. this function is invoked with only one argument), then the context value is used as the value of `str`.
If `str` does not contain chars, then it returns `str`.
**Examples**
| Expression | Result |
| ------------------------------------- | --------- |
| `$substringAfter("Hello World", " ")` | `"World"` |
## $uppercase
**Signature:** `$uppercase(str)`
**Parameters:**
* `str` - The source string.
Returns a string with all the characters of `str` converted to uppercase.
If `str` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `str`
**Examples**
| Expression | Result |
| --------------------------- | --------------- |
| `$uppercase("Hello World")` | `"HELLO WORLD"` |
## $lowercase
**Signature:** `$lowercase(str)`
**Parameters:**
* `str` - The source string.
Returns a string with all the characters of `str` converted to lowercase.
If `str` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `str`
**Examples**
| Expression | Result |
| --------------------------- | --------------- |
| `$lowercase("Hello World")` | `"hello world"` |
## $trim
**Signature:** `$trim(str)`
**Parameters:**
* `str` - The source string.
An error is thrown if `str` is not a string.
Normalizes and trims all whitespace characters in `str` by applying the following steps:
* All tabs, carriage returns, and line feeds are replaced with spaces.
* Contiguous sequences of spaces are reduced to a single space.
* Trailing and leading spaces are removed.
If `str` is not specified (i.e. this function is invoked with no arguments), then the context value is used as the value of `str`. An error is thrown if `str` is not a string.
**Examples**
| Expression | Result |
| -------------------------- | --------------- |
| `$trim(" Hello \t World")` | `"Hello World"` |
## $pad
**Signature:** `$pad(str, width [, char])`
**Parameters:**
* `str` - The source string.
* `width` - The desired width of the output.
If `width` is a positive number, then the `str` is padded to the right; if negative, it is padded to the left.
* `char` - The optional `char` argument specifies the padding character(s) to use.
If not specified, it defaults to the space character.
Returns a copy of the string `str` with extra padding, if necessary, so that its total number of characters is at least the absolute value of the `width` parameter. If width is a positive number, then the string is padded to the right; if negative, it is padded to the left. The optional `char` argument specifies the padding character(s) to use. If not specified, it defaults to the space character.
**Examples**
| Expression | Result |
| ------------------------------------- | ------------ |
| `$pad("foo", 5)` | `"foo "` |
| `$pad("foo", -5)` | `" foo"` |
| `$pad("foo", -5, "#")` | `"##foo"` |
| `$formatBase(35, 2) ~> $pad(-8, '0')` | `"00100011"` |
## $contains
**Signature:** `$contains(str, pattern)`
**Parameters:**
* `str` - The source string to search for a `pattern` in.
* `pattern` - The `pattern` parameter can either be a string or a regular expression (regex).
If it is a string, the function returns `true` if the characters within `pattern` are contained contiguously within `str`.
If it is a regex, the function will return `true` if the regex matches the contents of `str`.
Returns `true` if `str` is matched by `pattern`, otherwise it returns `false`. If `str` is not specified (i.e. this function is invoked with one argument), then the context value is used as the value of `str`.
The `pattern` parameter can either be a string or a regular expression (regex). If it is a string, the function returns `true` if the characters within `pattern` are contained contiguously within `str`. If it is a regex, the function will return `true` if the regex matches the contents of `str`.
**Examples**
| Expression | Result |
| ----------------------------------- | ------------------------------------------------- |
| `$contains("abracadabra", "bra")` | `true` |
| `$contains("abracadabra", /a.*a/)` | `true` |
| `$contains("abracadabra", /ar.*a/)` | `false` |
| `$contains("Hello World", /wo/)` | `false` |
| `$contains("Hello World", /wo/i)` | `true` |
| `Phone[$contains(number, /^077/)]` | `{ "type": "mobile", "number": "077 7700 1234" }` |
## $split
**Signature:** `$split(str, separator [, limit])`
**Parameters:**
* `str` - A string to split by the `pattern`.
* `pattern` - The `separator` parameter can either be a string or a regular expression (regex).
If it is a string, it specifies the characters within `str` about which it should be split.
If it is the empty string, `str` will be split into an array of single characters.
If it is a regex, it splits the string around any sequence of characters that match the regex.
* `limit` - The optional `limit` parameter is a number that specifies the maximum number of substrings to include in the resultant array. Any additional substrings are discarded.
If `limit` is not specified, then `str` is fully split with no limit to the size of the resultant array.
It is an error if `limit` is not a non-negative number.
Splits the `str` parameter into an array of substrings. If `str` is not specified, then the context value is used as the value of `str`. It is an error if `str` is not a string.
The `separator` parameter can either be a string or a regular expression (regex). If it is a string, it specifies the characters within `str` about which it should be split. If it is the empty string, `str` will be split into an array of single characters. If it is a regex, it splits the string around any sequence of characters that match the regex.
The optional `limit` parameter is a number that specifies the maximum number of substrings to include in the resultant array. Any additional substrings are discarded. If `limit` is not specified, then `str` is fully split with no limit to the size of the resultant array. It is an error if `limit` is not a non-negative number.
**Examples**
| Expression | Result |
| ----------------------------------------------------------- | ------------------------------------------------------ |
| `$split("so many words", " ")` | `["so", "many", "words"]` |
| `$split("so many words", " ", 2)` | `["so", "many"]` |
| `$split("too much, punctuation. hard; to read", /[ ,.;]+/)` | `["too", "much", "punctuation", "hard", "to", "read"]` |
## $join
**Signature:** `$join(array[, separator])`
**Parameters:**
* `array` - An array of strings to join together.
It is an error if the input array contains an item which isn't a string.
* `separator` - A string to join the `array` with.
If `separator` is not specified, then it is assumed to be the empty string, i.e. no separator between the component strings. It is an error if `separator` is not a string.
Joins an array of component strings into a single concatenated string with each component string separated by the optional `separator` parameter.
It is an error if the input array contains an item which isn't a string.
If `separator` is not specified, then it is assumed to be the empty string, i.e. no separator between the component strings. It is an error if `separator` is not a string.
**Examples**
| Expression | Result |
| ----------------------------------------------------------------------------- | -------------------------- |
| `$join(['a','b','c'])` | `"abc"` |
| `$split("too much, punctuation. hard; to read", /[ ,.;]+/, 3) ~> $join(', ')` | `"too, much, punctuation"` |
## $match
**Signature:** `$match(str, pattern [, limit])`
**Parameters:**
* `str` - A string to match by `pattern`.
* `pattern` - A regular expression (regex) used to search for matches within the `str`.
* `limit` - The optional `limit` parameter is a number that specifies the maximum number of matches to include in the resultant array. Any additional matches are discarded.
If `limit` is not specified, then there's no limit to the size of the resultant array.
It is an error if `limit` is not a non-negative number.
Applies the `str` string to the `pattern` regular expression and returns an array of objects, with each object containing information about each occurrence of a match within `str`.
The object contains the following fields:
* `match` - the substring that was matched by the regex.
* `index` - the offset (starting at zero) within `str` of this match.
* `groups` - if the regex contains capturing groups (parentheses), this contains an array of strings representing each captured group.
If `str` is not specified, then the context value is used as the value of `str`. It is an error if `str` is not a string.
**Examples**
| Expression | Result |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `$match("ababbabbcc",/a(b+)/)` | `[{ "match": "ab", "index": 0, "groups": ["b"] }, { "match": "abb", "index": 2, "groups": ["bb"] }, { "match": "abb", "index": 5, "groups": ["bb" ] }]` |
## $replace
**Signature:** `$replace(str, pattern, replacement [, limit])`
**Parameters:**
* `str` - The source string.
* `pattern` - The `pattern` parameter can either be a string or a regular expression (regex).
If it is a string, it specifies the substring(s) within `str` which should be replaced.
If it is a regex, its is used to find.
* `replacement` - The `replacement` parameter can either be a string or a function. If it is a string, it specifies the sequence of characters that replace the substring(s) that are matched by `pattern`. If `pattern` is a regex, then the `replacement` string can refer to the characters that were matched by the regex as well as any of the captured groups using a `$` followed by a number `N`:
* If `N = 0`, then it is replaced by substring matched by the regex as a whole.
* If `N > 0`, then it is replaced by the substring captured by the Nth parenthesised group in the regex.
* If `N` is greater than the number of captured groups, then it is replaced by the empty string.
* A literal `$` character must be written as `$$` in the `replacement` string
If the `replacement` parameter is a function, then it is invoked for each match occurrence of the `pattern` regex. The `replacement` function must take a single parameter which will be the object structure of a regex match as described in the `$match` function; and must return a string.
* `limit` - The optional `limit` parameter, is a number that specifies the maximum number of replacements to make before stopping. The remainder of the input beyond this limit will be copied to the output unchanged.
Finds occurrences of `pattern` within `str` and replaces them with `replacement`.
If `str` is not specified, then the context value is used as the value of `str`. It is an error if `str` is not a string.
The `pattern` parameter can either be a string or a regular expression (regex). If it is a string, it specifies the substring(s) within `str` which should be replaced. If it is a regex, its is used to find .
The `replacement` parameter can either be a string or a function. If it is a string, it specifies the sequence of characters that replace the substring(s) that are matched by `pattern`. If `pattern` is a regex, then the `replacement` string can refer to the characters that were matched by the regex as well as any of the captured groups using a `$` followed by a number `N`:
* If `N = 0`, then it is replaced by substring matched by the regex as a whole.
* If `N > 0`, then it is replaced by the substring captured by the Nth parenthesised group in the regex.
* If `N` is greater than the number of captured groups, then it is replaced by the empty string.
* A literal `$` character must be written as `$$` in the `replacement` string
If the `replacement` parameter is a function, then it is invoked for each match occurrence of the `pattern` regex. The `replacement` function must take a single parameter which will be the object structure of a regex match as described in the `$match` function; and must return a string.
The optional `limit` parameter, is a number that specifies the maximum number of replacements to make before stopping. The remainder of the input beyond this limit will be copied to the output unchanged.
**Examples**
| Expression | Result |
| -------------------------------------------------------- | --------------------------- |
| `$replace("John Smith and John Jones", "John", "Mr")` | `"Mr Smith and Mr Jones"` |
| `$replace("John Smith and John Jones", "John", "Mr", 1)` | `"Mr Smith and John Jones"` |
| `$replace("abracadabra", /a._?a/, "_")` | `"*c*bra"` |
| `$replace("John Smith", /(\w+)\s(\w+)/, "$2, $1")` | `"Smith, John"` |
| `$replace("265USD", /(\[0-9]+)USD/, "$$$1")` | `"$265"` |
## $eval
**Signature:** `$eval(str [, context])`
**Parameters:**
* `str` - A string with literal JSON or a JSONata expression.
Parses and evaluates the string `expr` which contains literal JSON or a JSONata expression using the current context as the context for evaluation.
**Examples**
| Expression | Result |
| --------------------------- | ----------- |
| `$eval("[1,2,3]")` | `[1, 2, 3]` |
| `$eval('[1,$string(2),3]')` | `[1,"2",3]` |
Optionally override the context by specifying the second parameter
## $base64encode
**Signature:** `$base64encode(str)`
**Parameters:**
* `str` - An ASCII string to encode.
Converts an ASCII string to a base 64 representation. Each each character in the string is treated as a byte of binary data. This requires that all characters in the string are in the 0x00 to 0xFF range, which includes all characters in URI encoded strings. Unicode characters outside of that range are not supported.
**Examples**
| Expression | Result |
| -------------------------------- | ------------------------ |
| `$base64encode("myuser:mypass")` | `"bXl1c2VyOm15cGFzcw=="` |
## $base64decode
**Signature:** `$base64decode(str)`
**Parameters:**
* `str` - An base64-encoded string to decode.
Converts base 64 encoded bytes to a string, using a UTF-8 Unicode codepage.
**Examples**
| Expression | Result |
| --------------------------------------- | ----------------- |
| `$base64decode("bXl1c2VyOm15cGFzcw==")` | `"myuser:mypass"` |
## $encodeUrlComponent
**Signature:** `$encodeUrlComponent(str)`
**Parameters:**
* `str` - An URL component string to encode.
Encodes a Uniform Resource Locator (URL) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.
**Examples**
| Expression | Result |
| -------------------------------- | --------------- |
| `$encodeUrlComponent("?x=test")` | `"%3Fx%3Dtest"` |
## $encodeUrl
**Signature:** `$encodeUrl(str)`
**Parameters:**
* `str` - An URL string to encode.
Encodes a Uniform Resource Locator (URL) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.
**Examples**
| Expression | Result |
| -------------------------------------------- | --------------------------------------------------------- |
| `$encodeUrl("https://mozilla.org/?x=шеллы")` | `"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"` |
## $decodeUrlComponent
**Signature:** `$decodeUrlComponent(str)`
**Parameters:**
* `str` - An encoded URL component string to decode.
Decodes a Uniform Resource Locator (URL) previously created by encodeUrl.
**Examples**
| Expression | Result |
| ------------------------------------ | ----------- |
| `$decodeUrlComponent("%3Fx%3Dtest")` | `"?x=test"` |
## $decodeUrl
**Signature:** `$decodeUrl(str)`
**Parameters:**
* `str` - An encoded URL string to decode.
Decodes a Uniform Resource Locator (URL) previously created by encodeUrl.
**Examples**
| Expression | Result |
| --------------------------------------------------------------------- | -------------------------------- |
| `$decodeUrl("https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B")` | `"https://mozilla.org/?x=шеллы"` |
# Boolean Operators
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-operators/boolean
***
## title: Boolean Operators
## `and` (Boolean AND)
The 'and' operator returns Boolean `true` if both operands evaluate to `true`. If either or both operands is not a Boolean type, then they are first cast to a Boolean using the rules of the `$boolean` function.
**Example**
## `or` (Boolean OR)
The 'or' operator returns Boolean `true` if either operand evaluates to `true`. If either or both operands is not a Boolean type, then they are first cast to a Boolean using the rules of the `$boolean` function.
**Example**
**Please note that Boolean 'NOT' is a [function](/edi-platform/mappings/jsonata/jsonata-functions/boolean#not), not an operator.**
# Comparison Operators
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-operators/comparison
***
## title: Comparison Operators
## `=` (Equals)
The equality operator returns Boolean `true` if both operands are the same (type and value). Arrays and objects are checked for deep equality. Arrays must have the same values in the same order. Objects must have the same key/value pairs (order is not relevant). Otherwise it returns `false`.
**Example**
## `!=` (Not equals)
The inequality operator returns Boolean `false` if both operands are the same (type and value, deep equality). Otherwise it returns `true`.
**Example**
## `>` (Greater than)
The 'greater than' operator returns Boolean `true` if the LHS is numerically greater than the RHS. Otherwise it returns `false`.
**Example**
## `<` (Less than)
The 'less than' operator returns Boolean `true` if the LHS is numerically less than the RHS. Otherwise it returns `false`.
**Example**
## `>=` (Greater than or equals)
The 'greater than or equals' operator returns Boolean `true` if the LHS is numerically greater than or equal to the RHS. Otherwise it returns `false`.
**Example**
## `<=` (Less than or equals)
The 'less than or equals' operator returns Boolean `true` if the LHS is numerically less than or equal to the RHS. Otherwise it returns `false`.
**Example**
## `in` (Inclusion)
The array (sequence) inclusion operator returns Boolean `true` if the value of the LHS is included in the array of values on the RHS. Otherwise it returns `false`. If the RHS is a single value, then it is treated as a singleton array.
**Example**
# JSONata Operators
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-operators
***
## title: JSONata Operators
Get started quickly with JSONata for mapping expressions. Automate complex
data transformations without a mess of lines and arrows.
* [Path Operators](/edi-platform/mappings/jsonata/jsonata-operators/path)
* [Numeric Operators](/edi-platform/mappings/jsonata/jsonata-operators/numeric)
* [Comparison Operators](/edi-platform/mappings/jsonata/jsonata-operators/comparison)
* [Boolean Operators](/edi-platform/mappings/jsonata/jsonata-operators/boolean)
* [Other Operators](/edi-platform/mappings/jsonata/jsonata-operators/other)
# Numeric Operators
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-operators/numeric
***
## title: Numeric Operators
## `+` (Addition)
The addition operator adds the operands to produce the numerical sum. It is an error if either operand is not a number.
**Example**
## `-` (Substraction/Negation)
The subtraction operator subtracts the RHS value from the LHS value to produce the numerical difference It is an error if either operand is not a number.
It can also be used in its unary form to negate a number
**Example**
## `*` (Multiplication)
The multiplication operator multiplies the operands to produce the numerical product. It is an error if either operand is not a number.
**Example**
## `/` (Division)
The division operator divides the RHS into the LHS to produce the numerical quotient. It is an error if either operand is not a number.
**Example**
## `%` (Modulo)
The modulo operator divides the RHS into the LHS using whole number division to produce a whole number quotient and a remainder. This operator returns the remainder. It is an error if either operand is not a number.
**Example**
## `..` (Range)
The sequence generation operator is used to create an array of monotonically increasing integer start with the number on the LHS and ending with the number on the RHS. It is an error if either operand does not evaluate to an integer. The sequence generator can only be used within an array constructor \[].
**Example**
# Other Operators
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-operators/other
***
## title: Other Operators
## `&` (Concatenation)
The string concatenation operator is used to join the string values of the operands into a single resultant string. If either or both of the operands are not strings, then they are first cast to string using the rules of the `$string` function.
**Example**
## `? :` (Conditional)
The conditional ternary operator is used to evaluate one of two alternative expressions based on the result of a predicate (test) condition. The operator takes the form:
` ? : `
The `` expression is first evaluated. If it evaluates to Boolean `true`, then the operator returns the result of evaluating the `` expression. Otherwise it returns the result of evaluating the `` expression. If `` evaluates to a non-Boolean value, then the value is first cast to Boolean using the rules of the `$boolean` function.
**Example**
## `:=` (Variable binding)
The variable binding operator is used to bind the value of the RHS to the variable name defined on the LHS. The variable binding is scoped to the current block and any nested blocks. It is an error if the LHS is not a `$` followed by a valid variable name.
**Example**
## `~>` (Chain)
The function chaining operator is used in the situations where multiple nested functions need to be applied to a value, while making it easy to read. The value on the LHS is evaluated, then passed into the function on the RHS as its first argument. If the function has any other arguments, then these are passed to the function in parenthesis as usual. It is an error if the RHS is not a function, or an expression that evaluates to a function.
**Examples**
`$uppercase($substringBefore($substringAfter(Customer.Email, "@"), "."))`
and
`$sum(Account.Order.Product.(Price * Quantity))`
can be more clearly written:
`Customer.Email ~> $substringAfter("@") ~> $substringBefore(".") ~> $uppercase()`
and
`Account.Order.Product.(Price * Quantity) ~> $sum()`
This operator can also be used in a more abstract form to define new functions based on a combination of existing functions. In this form, there is no value passed in on the LHS of the first function in the chain.
For example
creates a new function `$uppertrim` that performs `$trim` followed by `$uppercase`.
## `... ~> | ... | ... |` (Transform)
The object transform operator is used to modify a copy of an object structure using a pattern/action syntax to target specific modifications while keeping the rest of the structure unchanged.
The syntax has the following structure:
`head ~> | location | update [, delete] |`
where
* `head` evaluates to the object that is to be copied and transformed
* `location` evaluates to the part(s) within the copied object that are to be updated. The `location` expression is evaluated relative to the result of `head`. The result of evaluating `location` must be an object or array of objects.
* `update` evaluates to an object that is merged into the object matched by each `location`. `update` is evaluated relative to the result of `location` and if `location` matched multiple objects, then the update gets evaluated for each one of these. The result of (each) update is merged into the result of `location`.
* `delete` (optional) evaluates to a string or an array of strings. Each string is the name of the name/value pair in each object matched by `location` that is to be removed from the resultant object.
The `~>` operator is the operator for function chaining and passes the value on the left hand side to the function on the right hand side as its first argument. The expression on the right hand side must evaluate to a function, hence the `|...|...|` syntax generates a function with one argument.
Example:
`| Account.Order.Product | {'Price': Price * 1.2} |`
defines a transform that will return a deep copy the object passed to it, but with the `Product` object modified such that its `Price` property has had its value increased by 20%. The first part of the expression is the path location that specifies all of the objects within the overall object to change, and the second part defines an object that will get merged into the object(s) matched by the first part. The merging semantics is the same as that of the `$merge()` function.
This transform definition syntax creates a JSONata function which you can either assign to a variable and use multiple times, or invoke inline.
Example:
`payload ~> |Account.Order.Product|{'Price': Price * 1.2}|`
or:
`$increasePrice := |Account.Order.Product|{'Price': Price * 1.2}|`
This also has the benefit that multiple transforms can be chained together for more complex transformations.
In common with `$merge()`, multiple changes (inserts or updates) can be made to an object.
Example:
`|Account.Order.Product|{'Price': Price * 1.2, 'Total': Price * Quantity}|`
Note that the Total will be calculated using the original price, not the modified one (JSONata is declarative not imperative).
Properties can also be removed from objects. This is done using the optional `delete` clause which specifies the name(s) of the properties to delete.
Example:
`$ ~> |Account.Order.Product|{'Total': Price * Quantity}, ['Price', 'Quantity']|`
This copies the input, but for each `Product` it inserts a Total and removes the `Price` and `Quantity` properties.
# Path Operators
Source: https://www.stedi.com/docs/edi-platform/mappings/jsonata/jsonata-operators/path
***
## title: Path Operators
The path operators underpin the declarative nature of the map/filter/reduce processing model in JSONata.
## `.` (Map)
The dot operator is one of the fundamental building blocks in JSONata expressions. It implements the 'for each' or 'map' function that is common in many functional languages.
The dot operator performs the following logic:
* The expression on the LHS is evaluated to produce an array of values.
* If it evaluates to a single value, that is treated as equivalent to an array containing that single value
* If it evaluates to nothing (no match or empty array), then the result of the operator expression is nothing
* For each value in the LHS array in turn:
* The value is known as the *context* and is used as the basis for any relative path expression on the RHS. It is also accessible in the RHS expression using the `$` symbol.
* The RHS expression is evaluated to produce a value or array of values (or nothing). These values are appended to a combined array of results for the operator as a whole.
* The combined result of the operator is returned.
This operator is left associative meaning that the expression `a.b.c.d` is evaluated like `((a.b).c).d`; i.e. left to right
**Example**
## `[` ... `]` (Filter)
The filter operator (a.k.a predicate) is used to select only the items in the input sequence that satisfy the predicate expression contained between the square brackets.
If the predicate expression is an integer, or an expression that evaluates to an integer, then the item at that position (zero offset) in the input sequence is the only item selected for the result sequence.
If the number is non-integer, then it is rounded *down* to the nearest integer.
If the predicate expression is an array of integers, or an expression that evaluates to an array of integers, then the items at those positions (zero offset) in the input sequence is the only item selected for the result sequence.
If the predicate expression evaluates to any other value, then it is cast to a Boolean as if using the `$boolean()` function. If this evaluates to `true`, then the item is retained in the result sequence. Otherwise it is rejected.
See [Navigating JSON Arrays](https://docs.jsonata.org/simple#navigating-json-arrays) and [Predicates](https://docs.jsonata.org/predicate) for more details and examples.
## `^(` ... `)` (Order-by)
The order-by operator is used to sort an array of values into ascending or descending order according to one or more expressions defined within the parentheses.
By default, the array will be sorted into ascending order. For example:
`Account.Order.Product^(Price)`
sorts all of the products into order of increasing price (`Price` is a numeric field in the `Product` object).
To sort in descending order, the sort expression must be preceded by the `>` symbol. For example:
`Account.Order.Product^(>Price)`
sorts all of the products into order of decreasing price. The `<` symbol can be used to explicitly indicate ascending order, although that is the default behaviour.
Secondary (and more) sort expressions can be specified by separating them with commas (`,`). The secondary expression will be used to determine order if the primary expression ranks two values the same. For example,
`Account.Order.Product^(>Price,
## `{` ... `}` (Reduce)
The reduce operator can be used as the last step in a path expression to group and aggregate its input sequence into a single object.
The key/value pairs between the curly braces determine the groupings (by evaluating the key expression) and the aggregated values for each group.
See [Grouping and Aggregation](https://docs.jsonata.org/sorting-grouping#grouping) for more details.
## `*` (Wildcard)
This wildcard selects the values of all the properties of the context object. It can be used in a path expression in place of a property name, but it cannot be combined with other characters like a glob pattern. The order of these values in the result sequence is implementation dependent.
See [Wildcards](https://docs.jsonata.org/predicate#wildcards) for examples.
## `**` (Descendants)
This wildcard recursively selects the values of all the properties of the context object, and the properties of any objects contained within these values as it descends the hierarchy.
See [Navigate arbitrary depths](https://docs.jsonata.org/predicate#navigate-arbitrary-depths).
## `%` (Parent)
This will select the 'parent' of the current context value. Here, we define 'parent' to be the enclosing object which has the property representing the context value.
This is the only operation which searches 'backwards' in the input data structure. It is implemented by static analysis of the expression at [compile time](https://docs.jsonata.org/embedding-extending#jsonatastr) and can only be used within expressions that navigate through that target parent value in the first place.
If, for any reason, the parent location cannot be determined, then a static error (S0217) is thrown.
**Example**
This returns an array of objects for each product in each order in each account. Information from the enclosing Order and Account objects can be accessed using the parent operator.
The repeated combination of `%.%.` is used to access the grandparent and higher ancestors.
## `#` (Positional variable binding)
This can be used to determine at which position in the sequence the current context item is. It can be used following any map, filter or order-by stage in the path.
The variable is available for use within subsequent stages of the path (e.g. within filter predicates) and goes out of scope at the end of the path expression.
**Example**
This returns an array of objects for each book in the library where Kernighan is one of the authors. Each object contains the book's title and its position within the books array before it was filtered.
## `@` (Context variable binding)
This is used to bind the current context item (`$`) to a named variable. It can only be used directly following a map stage, not a filter or order-by stage.
The variable binding remains in scope for the remainder of the path expression.
Because the current context has now been explicitly bound to a named variable, this context will be carried forward to be the context of the next stage in the path.
For example, in this snippet of a path, `library.loans@$l.books`, the loans array is a property of the library object and each loan will, in turn, be bound to the variable `$l`.
The books array, which is also a property of the library object, will then be selected.
This operator can be used to perform data joins within a path because of its ability to do cross-referencing across objects.
**Example**
This performs an 'inner join' between objects in the loans array and objects in the books array where the ISBNs match between the structures.
Block expressions can be used to widen the scope of the data cross-referencing as shown in this example:
# Message Disposition Notifications (MDNs)
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/as2/as2-mdn-response
***
title: Message Disposition Notifications (MDNs)
sidebarTitle: MDN responses
---------------------------
AS2 supports MDN (message disposition notification), a way for your partner to acknowledge that they have received your message. Some partners may require that you request and accept an MDN response, send MDN responses, or both.
## What is an MDN?
An MDN (Message Disposition Notification) serves as a receipt to acknowledge that a message has been received and can verify various aspects of the message's integrity and authenticity.
You or your trading partners may request MDNs for the following reasons:
* **Acknowledge receipt:** An MDN serves as a verifiable acknowledgment that a message has been received by the trading partner's system.
* **Security**: If the sent message was signed, the MDN allows the sender to confirm that the receiving system has authenticated the sender and verified the message's integrity.
* **Non-Repudiation:** MDNs provide evidence that a message has been both received and processed, which can be essential in dispute resolution or auditing scenarios.
According the AS2 specification, MDNs can either be synchronous (provided on the same connection as the HTTP request) or asynchronous (sent separately after the initial HTTP request), depending on the requirements of a given partnership.
## Configure MDNs
For outbound messages, Stedi only supports accepting synchronous MDNs, so you need to tell your partner to send synchronous MDNs if they wish to send an MDN response. Visit [Requirements](/edi-platform/configure/trading-partners/connections/as2/as2-requirements#with-an-mdn-response-requested) for configuration details.
For inbound messages, Stedi automatically sends MDNs when requested. Stedi delivers MDNs either asynchronously or synchronously, depending on the specified parameters in your partner’s request. Visit [Requirements](/edi-platform/configure/trading-partners/connections/as2/as2-requirements#with-an-mdn-response-returned) for configuration details.
## View MDN responses
To view the MDN response associated with a file:
1. Go to the [Files](https://portal.stedi.com/app/core/file-executions) page and click the file to view its details.
2. Click **Connection deliveries**.
3. Under **MDN Status** click **View file**.
You can review the contents of the MDN response and optionally download it to your machine.
# AS2 Connections
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/as2/as2-overview
***
title: AS2 Connections
sidebarTitle: Overview
----------------------
The AS2 protocol is a popular protocol for securely exchanging EDI files. Stedi provides fully-managed AS2 connections that take care of the intricacies of AS2 and scale automatically to meet your demand.
## About AS2
You can technically use AS2 to exchange any type of file, but it is not commonly used outside of EDI.
AS2 and its predecessor, AS1, were designed to facilitate the secure exchange of business transactions using digital certificates and encryption prior to the popularization of HTTPS. AS2 was formalized in 2005 by the Internet Engineering Task Force (IETF) in [RFC 4130](https://www.rfc-editor.org/rfc/rfc4130). Despite the fact that HTTPS is now the de facto standard for secure message exchange, AS2 is still widely used throughout the business world. Modern AS2 connections, including those in the Stedi platform, can use both HTTP and HTTPS as the underlying transport protocol. The requirements for AS2 setup differ depending on whether you use HTTP or HTTPS.
Setting up an AS2 connection with a partner involves generating one or more public-private key pairs for use in encrypting and signing messages. Your partner will also need to generate their own key pairs, and then you and your partner will need to exchange public keys and agree upon an encryption algorithm.
## View connection logs
You can view and filter logs for each AS2 connection. You can view three types of logs:
* **Provisioning:** These logs detail each step to create or update the connection, such as provisioning the certificates, making it easier to diagnose errors.
* **Inbound:** These logs detail each file that your partner sends to you over the connection.
* **Outbound:** These logs detail each file that you generate and send to your partner over the connection.
To view logs, go to the partnership associated with the connection and click the connection to view its details page.
## Known limitations
* Server-side TCP keep-alive is not supported. The connection times out after 350 seconds of inactivity unless the client sends keep-alive packets.
* If an inbound message does not contain valid AS2 headers, it will not appear in the logs.
* Multiple attachments and certificate exchange messaging (CEM) from AS2 version 1.2 are not currently supported.
* For outbound messages, your partner's server must support the Cryptographic Message Syntax (CMS) algorithm protection attribute for validating message signatures, as defined in [RFC 6211](https://www.rfc-editor.org/rfc/rfc6211). This is not supported in certain older IBM Sterling products.
* For outbound messages over HTTPS, your partner's endpoint must support the TLS version 1.2 protocol and one of the following cryptographic algorithms:
* `TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256`
* `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`
* `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384`
* `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384`
* `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256`
* `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`
* `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384`
* `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`
* `TLS_RSA_WITH_AES_128_CBC_SHA256`
* `TLS_RSA_WITH_AES_256_CBC_SHA256`
# AS2 requirements
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/as2/as2-requirements
***
title: AS2 requirements
sidebarTitle: Requirements
--------------------------
There is certain base-level information that you will always need to exchange with
your partner prior to setting up an AS2 connection:
| Item | Usage |
| ---------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| Your partner's AS2 ID | Required |
| [Your AS2 ID](/edi-platform/configure/trading-partners/connections/as2/configure-as2#choose-your-as2-identifier) | Required |
| Your partner's AS2 server URL | Required if sending AS2 messages |
| [Your AS2 server URL](https://portal.stedi.com/app/core/settings) | Required if receiving AS2 messages |
The rest of the information you need to exchange with your partner depends on the scenario(s) you want to support, and your partner's requirements. The following scenarios help you understand how AS2 works and how you can use it to exchange transactions with your trading partners.
## Send AS2 messages to a partner
For outbound AS2 messages, the configuration requirements differ depending on several factors:
* Whether your partner's server uses HTTP or HTTPS
* Whether your partner requires you to sign your messages
* Whether your partner requires you to accept an MDN response
### Using HTTP without encryption
If your partner's server URL starts with `http://`, Stedi will send messages to your partner using standard HTTP. Since HTTP does not support encryption natively, Stedi must encrypt your messages according to the AS2 protocol before sending them to your partner.
The following table shows the configuration information you need to send AS2 messages to a partner over HTTP.
| Item | Usage | Comments |
| -------------------------------------------- | -------- | ------------------------------------------------------------------------------------------- |
| Your partner's public encryption certificate | Required | |
| Your partner's encryption algorithm | Required | Must be `AES128_CBC`, `AES192_CBC`, or `AES256_CBC` |
| Your partner's certificate chain | Optional | Required if your partner certificate was issued by a third-party Certificate Authority (CA) |
| Your public encryption certificate | Not used | |
| Your private encryption key | Not used | |
In this scenario, Stedi uses your partner's public encryption certificate and specified encryption algorithm to encrypt the message. Stedi then sends the encrypted message to your partner's server over HTTP, and your partner uses their private key to decrypt the message.
### Using HTTPS without signing
If your partner's server URL starts with `https://`, Stedi will send messages to your partner using HTTPS. Data transferred over HTTPS is natively encrypted, but some partners may also require you to encrypt the payload using AS2.
The following table shows the information you need to send AS2 messages to a partner over HTTP.
| Item | Usage | Comments |
| -------------------------------------------- | -------- | ------------------------------------------------------------------------------------------- |
| Your partner's public encryption certificate | Optional | |
| Your partner's encryption algorithm | Optional | If used, must be `AES128_CBC`, `AES192_CBC`, or `AES256_CBC` |
| Your partner's certificate chain | Optional | Required if your partner certificate was issued by a third-party Certificate Authority (CA) |
| Your public encryption certificate | Not used | |
| Your private encryption key | Not used | |
In this scenario, Stedi will use your partner's public encryption certificate (if provided) and specified encryption algorithm to encrypt the message payload according to the AS2 protocol. Stedi then sends the encrypted payload to your partner's server over HTTPS (which includes a layer of encryption). Your partner will decrypt the HTTPS request and the AS2 payload using private keys.
### Using HTTP or HTTPS with signing
Certain trading partners may also require you to sign your messages. Message signing allow partners to verify that your message is authentic and has not been tampered with. This is done by generating a public-private key pair and then sharing your public key with your partner. Your partner will then use your public key to verify that the message was sent by you.
Stedi will automatically sign your messages if you upload a signing certificate to your local profile.
Additional configuration:
| Item | Usage | Comments |
| --------------------------------- | -------- | ----------------------------------------------------------------------------------- |
| Your public signing certificate | Required | |
| Your private signing key | Required | |
| Your certificate chain | Optional | Required if your certificate was issued by a third-party Certificate Authority (CA) |
| Your partner's public certificate | Not used | |
### With an MDN response requested
Some partners may require that you request and accept an [MDN response](/edi-platform/configure/trading-partners/connections/as2/as2-mdn-response). If your partner signs their MDNs, you will need to import your partner's public signing certificate into Stedi to verify the MDN.
MDNs can be sent synchronously or asynchronously. For outbound messages, Stedi only supports accepting synchronous MDNs, so you need to tell your partner to send synchronous MDNs if they wish to send an MDN response.
Additional configuration:
| Item | Usage | Comments |
| ----------------------------------------- | -------- | ------------------------------------------------------------------------------------------- |
| Your partner's public signing certificate | Optional | Required if your partner signs MDNs |
| Your partner's certificate chain | Optional | Required if your partner certificate was issued by a third-party Certificate Authority (CA) |
| Your partner's MDN signing algorithm | Required | Can be `None`, `SHA1`, `SHA256`, `SHA384`, or `SHA512` |
## Receive AS2 messages from a partner
Receiving AS2 messages from a partner is similar to sending messages to a partner, but the process is reversed. In this case, your partner sends messages to Stedi's AS2 server, and you must provide them with the connection information.
Stedi's AS2 servers use HTTP, and therefore require that your partner encrypts their messages according to the AS2 protocol.
The following table shows the information needed for setting up an inbound AS2 connection.
| Item | Usage | Comments | Exchange with partner |
| ----------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------- | --------------------- |
| Your public encryption certificate | Required | Must be 2048-bit or 4096-bit RSA | Yes |
| Your private encryption key | Required | Must be 2048-bit or 4096-bit RSA | No |
| Your certificate chain | Optional | Required if your certificate was issued by a third-party Certificate Authority (CA) | Yes |
| Your encryption algorithm | Required | `AES128_CBC`, `AES192_CBC`, `AES256_CBC`, `3DES` | Yes |
| [Your AS2 server URL](https://portal.stedi.com/app/core/settings) | Required | | Yes |
In this scenario, your partner uses your public encryption certificate and specified encryption algorithm to encrypt the message payload. Your partner then sends the encrypted payload to Stedi's server over HTTP, and Stedi uses your private key to decrypt the payload.
### With signing
Certain trading partners may also require that you verify the authenticity and integrity of their messages using their signature. Your partner will generate a public-private key pair and then share their public key with you. When you upload this key to Stedi, Stedi uses it to verify that your partner was the party that sent the message.
Additional configuration:
| Item | Usage | Comments |
| ----------------------------------------- | -------- | ------------------------------------------------------------------------------------------- |
| Your partner's public signing certificate | Required | |
| Your partner's certificate chain | Optional | Required if your partner certificate was issued by a third-party Certificate Authority (CA) |
### With an MDN response returned
Your partner may request that you send an [MDN response](/edi-platform/configure/trading-partners/connections/as2/as2-mdn-response) acknowledging that you have received their message. Stedi automatically sends MDNs when requested in an inbound message and delivers them either asynchronously or synchronously, depending on the specified parameters in your partner's request.
Your trading partner's requests may specify that MDN responses should be signed. If a signed MDN is requested and you have imported your public and private signing keys, Stedi signs the MDN using the algorithm specified in the request. If you have not imported your signing keys, Stedi returns an unsigned MDN, as per RFC 4130 section 7.3.1.
Additional configuration:
| Item | Usage | Comments |
| ------------------------------- | -------- | ----------------------------------------------------------------------------------- |
| Your public signing certificate | Optional | |
| Your private signing key | Optional | |
| Your certificate chain | Optional | Required if your certificate was issued by a third-party Certificate Authority (CA) |
## Summary of required configuration
The following tables summarize the required configuration based on different scenarios.
**For all AS2 connections:**
| Item | Usage | Source |
| --------------------- | --------------- | -------------------------------------------- |
| Your partner's AS2 ID | Always required | Provided by partner |
| Your AS2 ID | Always required | [Self-assigned](#choose-your-as2-identifier) |
**For sending AS2 messages:**
| Item | Usage | Source |
| -------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| Your partner's AS2 server URL | Required | Provided by partner |
| Your partner's public encryption certificate | Required if using HTTP, optional if using HTTPS | Provided by partner |
| Your partner's encryption algorithm | Required if using HTTP, conditionally required if using HTTPS + AS2 encryption | Provided by partner |
| Your partner's certificate chain | Conditionally required if your partner certificate was issued by a third-party CA | Provided by partner |
| Your partner's public signing certificate | Required if MDNs will be returned | Provided by partner |
| Your partner's certificate chain | Conditionally required if your partner certificate was issued by a third-party CA | Provided by partner |
| Your public signing certificate | Optional if your partner requires signed messages | [Self-generated](#create-your-signing-and-encryption-certificates) or CA |
| Your private signing key | Optional if your partner requires signed messages | [Self-generated](#create-your-signing-and-encryption-certificates) |
| Your certificate chain | Conditionally required if your certificate was issued by a third-party CA | CA |
**For receiving AS2 messages:**
| Item | Usage | Source |
| ---------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| Your AS2 server URL | Required | [Core Settings page](https://portal.stedi.com/app/core/settings) |
| Your public encryption certificate | Required | [Self-generated](#create-your-signing-and-encryption-certificates) or CA |
| Your private encryption key | Required | [Self-generated](#create-your-signing-and-encryption-certificates) |
| Your certificate chain | Conditionally required if your certificate was issued by a third-party Certificate Authority (CA) | CA |
| Your encryption algorithm | Required | [Self-generated](#create-your-signing-and-encryption-certificates) |
| Your public signing certificate | Optional if your partner requires signed MDNs | [Self-generated](#create-your-signing-and-encryption-certificates) or CA |
| Your private signing key | Optional if your partner requires signed MDNs | [Self-generated](#create-your-signing-and-encryption-certificates) |
# Configure AS2 connections
Source: https://www.stedi.com/docs/edi-platform/configure/trading-partners/connections/as2/configure-as2
***
title: Configure AS2 connections
sidebarTitle: Configure
-----------------------
Once you have gathered the [required setup information](/edi-platform/configure/trading-partners/connections/as2/as2-requirements),
you can configure your Stedi AS2 connection.
## Choose your AS2 identifier
The AS2 protocol requires that the sender and receiver provide each other with AS2 IDs to help identify and route transactions during the AS2 file exchange process.
Your partner will provide their AS2 ID during the onboarding process.
There is no central authority that registers or tracks AS2 IDs, so you can choose any value you like. You should choose a value that is unlikely to be used by other companies. It's common to use the same value that you chose for [your `ISA` ID](/edi-platform/configure/trading-partners/profiles-and-partnerships#create-local-profile) when you created your Local profile.
An AS2 ID must be between 1-128 printable ASCII characters (except double quote or backslash), and is case sensitive. It's customary to use all capitalized letters and include no spaces.
## Create an AS2 connection
Creating an AS2 connection provisions all the resources required to send and receive data using the AS2 protocol. You can only create one AS2 connection per partnership.
To create an AS2 connection:
1. Go to the **Trading partners** page.
2. Click the partnership where you want to add the connection.
3. Click **Create connection**.
4. Select **AS2** as the **Connection type**.
5. Stedi generates an internal **Connection name**. This is never visible to your trading partner and is used for unique identification with your Stedi account only. You can specify a custom name if desired. You cannot edit the name after the connection has been created.
6. Leave **ISA validation options** as **Default** unless you're very sure you need a different setting for your use case.
7. Enter your **AS2 ID** as the **Local AS2 profile identifier**.
8. (Optional) Under Local profile signing credentials you can upload the three different certificates required:
* **Certificate:** Your public signing certificate
* **Private Key:** Your private signing key
* **Certificate chain:** Only required if you are using certificates and keys generated by a trusted certificate authority (CA)
9. (Optional) By default, your **Local profile encryption credentials** use the same data you supplied for your local signing credentials. If you are using different certificate and key for encryption, toggle **Same as signing credentials** to **OFF** and supply: -**Certificate:** Your public encryption certificate
* **Private Key:** Your private encryption key
* **Certificate chain:** Only required if you are using certificates and keys generated by a trusted certificate authority (CA)
10. Enter your trading partner's AS2 ID as the **Partner AS2 profile identifier**.
11. (Optional) Under **Partner profile signing credentials**, you can upload the two different certificates:
* **Certificate:** Your trading partners’ signing certificate
* **Certificate chain:** Only required when your trading partners are using certificates and keys generated by a trusted certificate authority (CA).
12. (Optional) By default, the **Partner profile encryption credentials** use the same data you supplied for your partner signing credentials. If your trading partner is using a different certificate and key for encryption, toggle **Same as signing credentials** to **OFF** and supply:
* **Certificate:** Your trading partner's public encryption certificate
* **Certificate chain:** Only required when your trading partner is using certificates and keys generated by a trusted certificate authority (CA)
13. (Optional) If you plan to send data to your trading partner, set the **Enable AS2 outbound** to **ON** and enter the **Partner AS2 server URL**, the **MDN response**, and **Encryption algorithm**.
* (Optional) If your trading partner requires **Basic authentication**, click **Advanced** > **Enable basic access authentication**, and enter the **Username** and **Password**.
14. (Optional) If you plan to receive data from your trading partner, set the **Enable AS2 inbound** to **ON** and enter the **Encryption algorithm**. Note that if this is the first time you are enabling inbound AS2, you must click **Enable inbound AS2** and wait for the server to be provisioned before you can finish creating the connection. This process provisions a unique server URL for you to share with your partners.
15. Click **Create connection**.
You must have enabled one or both of the Inbound or Outbound sections, before you can create the connection.
## Certificates and keys
Before you configure your AS2 connection, you need to prepare the certificates that you will use. This involves generating your own certificates as well as requesting certificates from your trading partner.
A certificate consists of both a public key and a private key. In AS2, there are two types of certificates:
* **Signing certificate:** This certificate allows you and your partners to verify the message sender's identity.
* **Encryption certificate:** This certificate allows you and your trading partners to encrypt and decrypt messages.
Some partners require two certificates – one for signing and one for encryption. Others may want you to use the same certificate for both tasks. For example, Walmart's AS2 portal only asks you to upload a single certificate. Follow the instructions from your trading partner when defining your AS2 configuration.
If either you or your partner are using a certificate issued by a third-party Certificate Authority (CA), you can skip the certificate creation steps and use the provided certificate and key directly.
If you are sending files to a trading partner's HTTPS endpoint, you must use
an SSL certificate signed by a publicly-trusted certificate authority (CA).
Self-signed certificates for HTTPS are not currently supported.
Certificates with the following cryptographic algorithms and key sizes are supported:
* 2048-bit RSA
* 4096-bit RSA
### Convert certificates and keys between formats
The format in which the encryption materials are provided to you by your trading partner may be different than the PEM format that Stedi AS2 requires. You can use OpenSSL utilities to convert certificates and keys between different formats.
Convert `CRT` to `PEM`:
`openssl x509 -in cert.crt -out cert.pem`
Convert `CER` to `PEM`:
`openssl x509 -in cert.cer -out cert.pem`
Convert `DER` to `PEM`:
`openssl x509 -in cert.der -out cert.pem`
### Create your signing and encryption certificates
If your trading partner requires unique certificates for signing and encryption, run the command twice. For each run, change the key names to indicate whether they are for signing or encryption. For example, use `acme-signing-private.pem` for the first run and `acme-encryption-private.pem` for the second run.
Create a new certificate. The `-days` option specifies the number of days the certificate will remain valid.
```bash
openssl req -x509 -newkey rsa:4096 -keyout .pem \
-out .pem -sha256 -days 365 -nodes
```
Enter information to identify your organization. You don’t need to fill out all the fields, but you should specify what you can.
## Static IP addresses
All AS2 connections in your Stedi account use the same set of static IP addresses for outbound EDI. If you need to allowlist these addresses, please [contact customer success](https://www.stedi.com/contact) for a full list.