Carequality Technical Guide

This guide is meant to assist all Redox community members in testing against the sandbox environments of Carequality Implementers. By following the instructions here, you will be able to test the search for patient matches, the identification of various patient documents, and the outbound retrieval of those documents.

You’ll also be able to sync your patient index with the Redox Carequality Gateway Responder. Which will enable Redox to respond to incoming patient queries on your behalf. This can reduce the burden of inbound queries to your infrastructure by as many as 200,000 requests per day!

The request snippets can be copied for use with curl, but comments will need to be removed (start with “//”) and any variables replaced (e.g. “{{variable here}}”). An easier option is to use the Postman collection and environment to test with the directions below.

Here is a Redox guide on Postman.

Setup

API Authentication

Authentication for Carequality is identical to authentication used for traditional Redox use cases. You can follow the instructions here and the quickstart videos here to learn more. Authentication is also included in the Postman collection above.

Subscriptions

Use the Carequality Connection Wizard to create a source and connect it to the Carequality Staging endpoints.

  • Carequality Staging Organizational Directory (XML)
  • Carequality Staging – XCPD
  • Carequality Staging – XCA

Organization

Querying for Organizations

API Details 

The first thing you’ll want to do is to explore the Carequality network. The Organization.Query API gives you the ability to search for organizations on various parameters, such as name, organizational identifier, or date of last update.

Request

First, test the API by making an API call based on the organizational identifier. Let’s pull the Redox organization from the sandbox directory:

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token from auth process}}" \
-d '{
  "Meta": {
    "DataModel": "Organization",
    "EventType": "Query",
    "EventDateTime": "2020-01-29T16:50:32.401Z",
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ]
  },
  "Directory": "Carequality",
  "Identifier": {
    "ID": "2.16.840.1.113883.3.6147", // The organizational identifier for Redox
    "IDType": "OID"
  }
}'

Response

You should see this response:

{
  "Paging": {
    "Count": "1" // one organization was found
  },
  "Organizations": [
    {
      "Address": {
        "Country": "USA",
        "ZIP": "53704",
        "State": "",
        "City": "Madison",
        "Streetaddress": ""
      },
      // Carequality organizations may have one or more contacts of different types
      "Contacts": [
        {
          "PhoneNumber": {
            "Work": ""
          },
          "EmailAddresses": ["[email protected]"],
          "Name": "PointClickCare Carequality Support",
          "Purpose": "Technical"
        }
      ],
      // This section identifies if the organization is part of another
      // Redox is an implementer, so we are not part of another organization
      "PartOf": {
        "Identifier": {
          "System": "http://www.hl7.org/oid/",
          "Type": "HCID",
          "Value": ""
        }
      },
      // This section lists the organization's OID as well as other identifiers
      "Identifiers": [
        {
          "IDType": "OID",
          "ID": "2.16.840.1.113883.3.6147"
        }
      ],
      "Active": "true",
      "Aliases": "",
      "Name": "Redox"
    }
  ],
  "Directory": "Carequality",
  "Meta": {
    "DataModel": "Organization",
    "EventType": "Query",
    "Message": {
      "ID": 4656136205
    },
    "Source": {
      "ID": "7f296bb4-83fd-498d-92f3-a76960648788"
    },
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ]
  }
}

You can try other search variations, such as name-based search:

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token}}" \
-d '{
  "Meta": {
    "DataModel": "Organization",
    "EventType": "Query",
    "EventDateTime": "2020-01-29T16:50:32.401Z",
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ]
  },
  "Directory": "Carequality",
  "NameSearch": {
    "Value": "Redox",
    "SearchType": "exact"
  }
}'

This should return the same response as the first query.

Explore the Organization.Query API more with different parameters and then head to the next section.

Adding, Updating and Deleting Organizations

API Details 

After you’ve started to see the other organizations on the Carequality network, you can now start to manage your own organization(s) on the network. The Organization.New API gives you the ability to create a new organization or facility.

Creation

The Organization.New API contains all of the information relevant to your or your healthcare organization customer’s institution. Read more below.

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token}}" \
-d '{
  "Meta": {
    "DataModel": "Organization",
    "EventType": "New",
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ]
  },
  "Directory": "Carequality", // Currently, only Carequality is supported
  "Action": "Create",
  "Organizations": [
    {
      "Name": "My Company",
      // The destination ID should be your Redox destination UUID where you
      // will receive inbound traffic (you can use null for testing)
      "DestinationID": "5e3dc12b-3a04-438e-880d-a690639e629e",
      "Aliases": ["My Company, LLC", "MY"],
      "Active": true,
      // OID is the only required identifier, but you can include your own identifiers as needed
      "Identifiers": [
        {
          "ID": "{{Your base OID here}}",
          "IDType": "OID"
        },
        {
          "ID": "0928",
          "IDType": "Local Facility Identifier"
        }
      ],
      // This section should be replaced with your contact information
      "Contacts": [
        {
          "Purpose": "Technical",
          "Name": "Redox Carequality Support - Test",
          "EmailAddresses": ["[email protected]"],
          "PhoneNumber": {
            "Work": "+16085359501",
            "Mobile": "+16085359501"
          }
        }
      ],
      // This section should be replaced with your address information
      "Address": {
        "StreetAddress": "2020 Eastwood Dr",
        "City": "Madison",
        "State": "WI",
        "ZIP": "53704",
        "County": "Dane",
        "Country": "USA"
      }
    }
  ]
}'

After you’ve sent a request in, you will receive a synchronous response indicating creation:

{
  "Meta": {
    "DataModel": "Organization",
    "EventType": "New",
    "Message": {
      "ID": 4606153124
    },
    "Source": {
      "ID": "7f296bb4-83fd-498d-92f3-a76960648788",
    },
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ],
    "Extensions": {
      "ResponseDetail": {
        "string": "New organization was added successfully."
      }
    }
  }
}

We can also create a subordinate organization using the PartOf field. We’ll create two facilities using this field:

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token}}" \
-d '{
  "Meta": {
    "DataModel": "Organization",
    "EventType": "New",
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ]
  },
  "Directory": "Carequality",
  "Action": "Create",
  "Organizations": [
    {
      "Name": "My Company Facility 1",
      "DestinationID": "5e3dc12b-3a04-438e-880d-a690639e629e",
      "Active": true,
      "Identifiers": [
        {
          "ID": "{{Your base OID here}}.1",
          "IDType": "OID"
        }
      ],
      // This references your top-level organization
      "PartOf": {
        "Identifier": {
          "Value": "{{Your base OID here}}"
        }
      },
      "Contacts": [
        {
          "Purpose": "Technical",
          "Name": "Redox Carequality Support - Test",
          "EmailAddresses": ["[email protected]"],
          "PhoneNumber": {
            "Work": "+16085359501",
            "Mobile": "+16085359501"
          }
        }
      ],
      "Address": {
        "StreetAddress": "2020 Eastwood Dr",
        "City": "Madison",
        "State": "WI",
        "ZIP": "53704",
        "County": "Dane",
        "Country": "USA"
      }
    }
  ]
}'
curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token}}" \
-d '{
  "Meta": {
    "DataModel": "Organization",
    "EventType": "New",
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ]
  },
  "Directory": "Carequality",
  "Action": "Create",
  "Organizations": [
    {
      "Name": "My Company Facility 2",
      "DestinationID": "5e3dc12b-3a04-438e-880d-a690639e629e",
      "Active": true,
      "Identifiers": [
        {
          "ID": "{{Your base OID here}}.2",
          "IDType": "OID"
        }
      ],
      // This references your top-level organization
      "PartOf": {
        "Identifier": {
          "Value": "{{Your base OID here}}"
        }
      },
      "Contacts": [
        {
          "Purpose": "Technical",
          "Name": "Redox Carequality Support - Test",
          "EmailAddresses": ["[email protected]"],
          "PhoneNumber": {
            "Work": "+16085359501",
            "Mobile": "+16085359501"
          }
        }
      ],
      "Address": {
        "StreetAddress": "995 Market St",
        "City": "San Francisco",
        "State": "CA",
        "ZIP": "94103",
        "Country": "USA"
      }
    }
  ]
}'

Using this API, we can create an organizational structure for our organization and underlying facilities. Here’s an example you can find in the sandbox:

The organization directory has the flexibility to build detailed hierarchies of two, three, or more levels. Your Redox representative can help provide guidance on best practices of organizational structure. For now, you should create at least one organization.

Updating and Deleting

After you’ve created an organization, you can use the Organization.Update API to change organizational details, such as address or contact information. 

You can also delete the organization within the directory using this API. Note that this does not fully remove all information, but instead marks the facility as inactive.

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token}}" \
-d '{
  "Meta": {
    "DataModel": "Organization",
    // Everything can stay the same as New except here and the "Action" field below
    "EventType": "Update",
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ]
  },
  "Directory": "Carequality",
  // This must also change to "Update"
  "Action": "Update",
  "Organizations": [
    {
      "Name": "My Company Facility 1 Update",
      "DestinationID": "5e3dc12b-3a04-438e-880d-a690639e629e",
      // This will effectively "delete" the organization
      "Active": false,
      "Identifiers": [
        {
          "ID": "{{Your base OID here}}.1",
          "IDType": "OID"
        }
      ],
      // This references the top-level Redox organization
      "PartOf": {
        "Identifier": {
          "Value": "{{Your base OID here}}"
        }
      },
      "Contacts": [
        {
          "Purpose": "Technical",
          "Name": "Redox Carequality Support - Test",
          "EmailAddresses": ["[email protected]"],
          "PhoneNumber": {
            "Work": "+16085359501",
            "Mobile": "+16085359501"
          }
        }
      ],
      "Address": {
        "StreetAddress": "2020 Eastwood Dr",
        "City": "Madison",
        "State": "WI",
        "ZIP": "53704",
        "County": "Dane",
        "Country": "USA"
      }
    }
  ]
}'

After a successful update, you’ll receive a response in this format:

{
  "Meta": {
    "DataModel": "Organization",
    "EventType": "Update",
    "Message": {
      "ID": 4606153124
    },
    "Source": {
      "ID": "7f296bb4-83fd-498d-92f3-a76960648788"
    },
    "Destinations": [
      {
        "ID": "a07afe3b-d247-4415-827f-6837707e1b8b"
      }
    ],
    "Extensions": {
      "ResponseDetail": {
        "string": "Organization with id:2.16.840.1.113883.3.6147.5 has been updated successfully."
      }
    }
  }
}

Errors

The following scenarios are defined errors by Carequality when adding, modifying, or deleting organizations:

  • 403 – <OID> already exists
  • 403 – Failed to parse request body as XML resource because your request body has to contain at least one identifier element
  • 403 – Failed to parse request body as XML resource because your request body has to contain valid type element.
  • 403 – Failed to parse request body as XML resource because your request body has to contain at least one Contact element. (Implementer only)
  • 403 – Failed to parse request body as XML resource because in your request body, some of endpoints have invalid display name.
  • 403 – id:<ID> is not valid. (on a put/update or delete)
  • 404 – Not Found
  • 500 – Parsing XML Request Error!
  • 500 – Your Organization Source contains duplicate business!

Frequently Asked Questions

What are OIDs? Why are they important?

An OID is a globally unique ISO (International Organization for Standardization) identifier. They are important in the context of Carequality in that they uniquely identify organizations in the network. When creating your organization and facilities, you’ll need to use an OID as the primary identifier. You can read more about OIDs here.

What OID should I use when creating my organization?

Redox has a base OID and is a Registration Authority, so you will have an OID branch assigned for your use. This will typically be a branch off of the base OID 2.16.840.1.113883.3.6147.458.  

Alternatively, you can register and pay HL7 for an independent OID branch. Work with your Redox representative to determine the best strategy for your organizational identifiers.

PatientSearch

Finding a Patient

API Details

After you’ve used the Organization Data Model to identify external organizations you’re interested in querying, you can use PatientSearch.Query to search that organization to see if your patient exists there.

Metadata

For this API and subsequent transactions, in order to comply with Carequality rules, we need to include some specific information properly identifying the querying user and their organization, as well as the target organization. We use a number of extensions in the Meta tag within the JSON for this purpose.

{
  "Meta": {
    "DataModel": "PatientSearch",
    "EventType": "Query",
    "Destinations": [
      {
        "ID": "1ca254a8-8d42-4593-abb4-b21399d9de57"
      }
    ],
    // This field is used to list the organization to be queried
    "FacilityCode": "{{OID of facility to be queried}}",
    "Extensions": {
      // This extension is used to identify the querying organization's OID
      "sender-organization-id": {
        "string": "{{Your OID here}}"
      },
      // This extension is used to identify the querying organization name, generally the name of your covered entity.
      "organization-name": {
        "string": "Beverly Hills Telehealth"
      },
      // This extension should include the name of the querying user
      "user-id": {
        "string": "Doolittle, John"
      },
      // This extension should include the role of the querying user.
      // You may use SNOMED, but any codeset can be used.
      "user-role": {
        "coding": {
          "code": "112247003",
          "display": "Medical Doctor"
        }
      },
      // This will default to TREATMENT if not specified
      "purpose-of-use": {
        "coding": {
          "code": "TREATMENT"
        }
      }
    }
  }
}

Request Format

In the body of the request, you should include the patient’s demographics. The table below contains information about test patients available across the Carequality sandbox network:

Organization CRISP Epic Ellkay Zen Redox
OID 2.16.840.1.1.13883.3.65 1.2.840.114350.1.13.0.1.7.3.688884.100 2.25.133064011062343676741887006899387521821 2.16.840.1.113883.3.8073.1000.1 2.16.840.1.113883.3.6147
First Name Gilbert Ferdinand John Jack Myra
Middle Name Fester
Last Name Grape Tapestry Smith O’Neill Jones
Date of Birth 1984-01-01 2003-09-29 1984-08-05 1984-01-01 1947-05-01
Sex Male Male Male Male Female
Address 4145 Earl C Atkins Dr 123 Milky Way 900 Somewhere Ct 100 Air Force Rd 1357 Amber Drive
City River Madison Wishful Cheyenne Beaverton
State WV WI NJ WY OR
Zip 26000 53717 07555 82001 97006

Example for CRISP

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token}}" \
-d '{
  "Meta": {
    "DataModel": "PatientSearch",
    "EventType": "Query",
    "Destinations": [
      {
        "ID": "1ca254a8-8d42-4593-abb4-b21399d9de57"
      }
    ],
    // This field is used to list the organization to be queried
    "FacilityCode": "2.16.840.1.113883.3.651",
    "Extensions": {
      // This extension is used to identify the querying organization's OID
      "sender-organization-id": {
        "string": "urn:oid:{{Your base OID here}}"
      },
      // This extension should inclde the name of the querying user
      "user-id": {
        "string": "Doolittle, John"
      },
      // This extension should include the role of the querying user.
      // You may use SNOMED, but any codeset can be used.
      "user-role": {
        "coding": {
          "code": "112247003",
          "display": "Medical Doctor"
        }
      },
      // This will default to TREATMENT if not specified
      "purpose-of-use": {
        "coding": {
          "code": "TREATMENT"
        }
      }
    }
  },
  "Patient": {
    "Identifiers": [],
    "Demographics": {
      "FirstName": "Gilbert",
      "LastName": "Grape",
      "DOB": "1984-01-01",
      "Sex": "Male",
      "Address": {
        "StreetAddress": "4145 Earl C Atkins Dr",
        "City": "River",
        "State": "WV",
        "ZIP": "26000"
      }
    }
  }
}'

This should result in a response with a match similar to the following:

{
  "Patient": {
    "Demographics": {
      "Address": {
        "County": null,
        "Country": null,
        "ZIP": "26000",
        "State": "WV",
        "City": "River",
        "StreetAddress": "4145 Earl C Atkins Dr"
      },
      "EmailAddresses": [],
      "PhoneNumber": {
        "Work": null,
        "Mobile": null,
        "Home": null
      },
      "Sex": "Male",
      "DOB": "1984-01-01",
      "LastName": "Grape",
      "FirstName": "Gilbert",
      "SSN": ""
    },
    "Identifiers": [
      {
        "IDType": "2.16.840.1.113883.3.651.1.1",
        "ID": "31131416"
      }
    ]
  },
  "Meta": {
    "DataModel": "PatientSearch",
    "EventType": "Query",
    "Message": {
      "ID": 4661084293
    },
    "Source": {
      "ID": "7f296bb4-83fd-498d-92f3-a76960648788"
    },
    "Destinations": [
      {
        "ID": "1ca254a8-8d42-4593-abb4-b21399d9de57"
      }
    ]
  }
}

Here are additional CRISP test patients:

CRISPID First Last DOB Gender Street City State Zip Alert Details
31131416 Gilbert Grape 1984-01-01 Male 4145 Earl C Atkins Dr River WV 26000 ENS, Care Alerts, CCDs
32195216 Solonia Testpatient 1955-01-01 Female 123 Test Street Name Salisbury MD 21804 CCD
79559712 Anna Cadence 1981-11-16 Female 1021 Main Street Columbia MD 21045 Alerts, CCD
79707202 Luke Vader 1977-07-12 Male 123 One Main Street Baltimore MD 21045 CCD
311355651 Chad Testpatient 1970-02-01 Male 555 N. Dale Drive Columbus OH 43215 OPTED OUT
11111111 Patient No 1901-01-01 Female 123 Rustic Dr Annapolis MD 21401 Does not exist

Frequently Asked Questions

What demographic information should I include in my queries?

At a minimum, you should include:

  • First name
  • Last Name
  • Date of Birth
  • Sex
  • Address

It is best practice to include as much information as possible. Most responding systems use advanced matching algorithms that have higher success rates as more information is included. Other valuable data points you may include:

  • Social Security Number
  • Phone numbers
  • Email

ClinicalSummary

Finding the List of Documents

API Details

Once you’ve found a patient’s external ID at an organization, you can use ClinicalSummary.DocumentQuery to determine the list of documents available for the patient.

Metadata

As mentioned for PatientSearch section above, you should include the same extensions in the Meta tag within the JSON.

Request Format

In the body of the request, you must include the patient’s ID and ID Type you received in the response of the PatientSearch. The table below contains information about test patients available across the Carequality sandbox network:

Organization CRISP Epic Ellkay Zen Redox
OID 2.16.840.1.1.13883.3.65 1.2.840.114350.1.13.0.1.7.3.688884.100 2.25.133064011062343676741887006899387521821 2.16.840.1.113883.3.8073.1000.1 2.16.840.1.113883.3.6147
First Name Gilbert Ferdinand John Jack Myra
Last Name Grape Tapestry Smith O’Neill Jones
ID 31131416 OPE0020200 1 T-SG10001 4442362
ID Type 1.3.6.1.4.1.21367.2010.1.2.300.10 1.2.840.114350.1.13.0.1.7.3.688884.100 2.25.133064011062343676741887006899387521821 2.16.840.1.113883.3.8073.1000.1 MR

Example for CRISP

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token}}" \
-d '{
  "Meta": {
    "DataModel": "Clinical Summary",
    "EventType": "DocumentQuery",
    "EventDateTime": "2019-08-02T20:09:22.089Z",
    "Destinations": [
      {
        "ID": "ec745338-8849-43ad-a7ce-4bc5bf1d8b89"
      }
    ],
    "FacilityCode": "2.16.840.1.113883.3.651",
    "Extensions": {
      "sender-organization-id": {
        "string": "urn:oid:{{Your base OID here}}"
      },
      "user-id": {
        "string": "Doolittle, John"
      },
      "user-role": {
        "coding": {
          "code": "112247003",
          "display": "Medical Doctor"
        }
      },
      "purpose-of-use": {
        "coding": {
          "code": "TREATMENT"
        }
      }
    }
  },
  "Patient": {
    "Identifiers": [
      {
        "ID": "31131416",
        "IDType": "1.3.6.1.4.1.21367.2010.1.2.300.10"
      }
    ]
  },
  "Document": {
    "StartDate": "2019-10-24T23:54:41.827Z",
    "EndDate": null,
    "Types": [
      {
        "Code": "18842-5",
        "Codeset": "http://hl7.org/fhir/ValueSet/c80-doc-typecodes",
        "Name": "Discharge summary"
      }
    ]
  }
}'

This should result in a response with a match similar to the following:

{
  "Meta": {
    "DataModel": "Clinical Summary",
    "EventType": "DocumentQuery",
    "Message": {
      "ID": 3800345541
    },
    "Source": {
      "ID": "f6e9f1dc-8148-496f-a3b2-c60a6d75cef4"
    },
    "Destinations": [
      {
        "ID": "ec745338-8849-43ad-a7ce-4bc5bf1d8b89"
      }
    ]
  },
  "Patient": {
    "Identifiers": [
      {
        "ID": "31131416",
        "IDType": "1.3.6.1.4.1.21367.2010.1.2.300.10"
      }
    ]
  },
  "Document": [
    {
      "Type": {
        "Name": "Alerts Repository Document",
        "Codeset": "LOINC",
        "Code": "34133-9"
      },
      "HCID": "urn:oid:2.16.840.1.113883.3.651",
      "RepositoryUniqueId": "1.3.6.1.4.1.21367.2010.1.2.300.10",
      "ID": "d0005626-513e-d1db-3e51-dbd1265600d0^1.3.6.1.4.1.21367.2010.1.2.300.10^urn:oid:2.16.840.1.113883.3.651"
    }
  ]
}

Frequently Asked Questions

I’m getting a lot of documents back on the response. What can I do?

ClinicalSummary.DocumentQuery has a number of useful parameters you can use to limit the number of documents returned or to find the documents that are relevant for you. Not all parameters are supported by all vendors. When supported, using the Visit.StartDate parameter can help you pull documents after a given date of service.

Retrieving a Document

API Details

After you’ve reviewed the list of documents, you can use the ClinicalSummary.DocumentGet to retrieve from an external organization.

Metadata

As mentioned in the previous sections, you should include the same extensions in the Meta tag within the JSON.

Request Format

In the body of the request, you must include the document ID you received in the response of the DocumentQuery. 

Example for CRISP

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token}}" \
-d '{
  "Meta": {
    "DataModel": "Clinical Summary",
    "EventType": "DocumentGet",
    "EventDateTime": "2019-08-02T20:09:22.089Z",
    "Destinations": [
      {
        "ID": "ec745338-8849-43ad-a7ce-4bc5bf1d8b89"
      }
    ],
    "FacilityCode": "2.16.840.1.113883.3.651",
    "Extensions": {
      "sender-organization-id": {
        "string": "urn:oid:{{Your base OID here}}"
      },
      "user-id": {
        "string": "Doolittle, John"
      },
      "user-role": {
        "coding": {
          "code": "112247003",
          "display": "Medical Doctor"
        }
      },
      "purpose-of-use": {
        "coding": {
          "code": "TREATMENT"
        }
      }
    }
  },
  "Document": {
    "ID": "d0005626-513e-d1db-3e51-dbd1265600d0^1.3.6.1.4.1.21367.2010.1.2.300.10^urn:oid:2.16.840.1.113883.3.651"
  }
}'

This should result in a response with a match similar to the following:

{
  "Meta": {
    "DataModel": "Clinical Summary",
    "EventType": "DocumentGet",
    "Message": {
      "ID": 3800345541
    },
    "Source": {
      "ID": "f6e9f1dc-8148-496f-a3b2-c60a6d75cef4"
    },
    "Destinations": [
      {
        "ID": "ec745338-8849-43ad-a7ce-4bc5bf1d8b89"
      }
    ]
  },
  "Patient": {
    "Identifiers": [
      {
        "ID": "31131416",
        "IDType": "1.3.6.1.4.1.21367.2010.1.2.300.10"
      }
    ]
  },
  "Data": "<xml contents="">",
  "FileType": "text/xml"
}
</xml>

Frequently Asked Questions

DocumentGet returns the full XML document. Why is that?

Some customers have pre-built capabilities to render XML C-CDA documents. Additionally, there are many open source CDA renderers (such as this one or this one) available that can be useful in viewing the document. We offer the option to return the XML document for this reason. If you’d like the ClinicalSummary contents in JSON format only, let your Redox representative know and they can help configure that setting.

Responding to Queries

A requirement of membership on the Carequality network is that every organization must also make available its patient data for others to query. Redox customers on the Carequality network have full latitude to handle incoming queries themselves, however, the volume of requests on the network can make that a challenging task.

The Redox Carequality Gateway

Organizations in the network, including yours, are trying to find patients within the network constantly. Rather than requiring that you respond to this volume of requests, Redox can provide you access to the Redox Carequality Gateway. This gateway acts as a repository that sits between the rest of the network and you. By pushing your PatientAdmin data to our repository, Redox can handle all queries from the rest of the network.

In order for the Redox Carequality Gateway to have the data we need, however, this requires that you send PatientAdmin data to Redox through the subscription created in the wizard. The following PatientAdmin event types are required to be sent to this location:

You can read more about each of these event types with the links above. An example of each of these is included in the Postman collection and with the curl commands in the next sections.

New Patient

Any time a new patient is created in your system, a message similar to the following should be sent:

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token from auth process}}" \
-d '{
	"Meta": {
		"DataModel": "PatientAdmin",
		"EventType": "NewPatient",
		"EventDateTime": "2019-10-24T22:04:47.915Z",
		"Test": true,
		"Destinations": [
			{
				"ID": "377a1892-378a-4475-ae27-87f17648770e",
				"Name": "RLS Destination"
			}
		]
	},
	"Patient": {
		"Identifiers": [
			{
				"ID": "{{some random prefix here such as your org OID}}.1",
				"IDType": "MR"
			},
			{
				"ID": "e167267c-16c9-4fe3-96ae-9cff5703e90a",
				"IDType": "EHRID"
			},
			{
				"ID": "a1d4ee8aba494ca",
				"IDType": "NIST"
			}
		],
		"Demographics": {
			"FirstName": "Timothy",
			"MiddleName": "Paul",
			"LastName": "Bixby",
			"DOB": "2008-01-06",
			"SSN": "101-01-0001",
			"Sex": "Male",
			"Race": "White",
			"IsHispanic": null,
			"MaritalStatus": "Married",
			"IsDeceased": null,
			"DeathDateTime": null,
			"PhoneNumber": {
				"Home": "+18088675301",
				"Office": null,
				"Mobile": null
			},
			"EmailAddresses": [],
			"Language": "en",
			"Citizenship": [],
			"Address": {
				"StreetAddress": "4762 Hickory Street",
				"City": "Monroe",
				"State": "WI",
				"ZIP": "53566",
				"County": "Green",
				"Country": "US"
			}
		},
		"Notes": [],
		"Contacts": [
			{
				"FirstName": "Barbara",
				"MiddleName": null,
				"LastName": "Bixby",
				"Address": {
					"StreetAddress": "4762 Hickory Street",
					"City": "Monroe",
					"State": "WI",
					"ZIP": "53566",
					"County": "Green",
					"Country": "US"
				},
				"PhoneNumber": {
					"Home": "+18088675303",
					"Office": "+17077543758",
					"Mobile": "+19189368865"
				},
				"RelationToPatient": "Mother",
				"EmailAddresses": [
					"[email protected]"
				],
				"Roles": [
					"Emergency Contact"
				]
			}
		],
		"Allergies": [
			{
				"Code": "7982",
				"Codeset": "RxNorm",
				"Name": "Penicillin",
				"Type": {
					"Code": null,
					"Codeset": null,
					"Name": null
				},
				"OnsetDateTime": null,
				"Reaction": [
					{
						"Code": "28926001",
						"Codeset": "SNOMED CT",
						"Name": "Rash"
					},
					{
						"Code": "247472004",
						"Codeset": "SNOMED CT",
						"Name": "Hives"
					}
				],
				"Severity": {
					"Code": null,
					"Codeset": null,
					"Name": null
				},
				"Status": null
			}
		],
		"PCP": {
			"NPI": "4356789876",
			"ID": "4356789876",
			"IDType": "NPI",
			"FirstName": "Pat",
			"LastName": "Granite",
			"Credentials": [
				"MD"
			],
			"Address": {
				"StreetAddress": "123 Main St.",
				"City": "Madison",
				"State": "WI",
				"ZIP": "53703",
				"County": "Dane",
				"Country": "USA"
			},
			"EmailAddresses": [],
			"PhoneNumber": {
				"Office": "+16085551234"
			},
			"Location": {
				"Type": null,
				"Facility": null,
				"Department": null,
				"Room": null
			}
		},
		"Guarantor": {
			"Number": "10001910",
			"FirstName": "Kent",
			"MiddleName": null,
			"LastName": "Bixby",
			"SSN": null,
			"DOB": null,
			"Sex": null,
			"Spouse": {
				"FirstName": "Barbara",
				"LastName": "Bixby"
			},
			"Address": {
				"StreetAddress": "4762 Hickory Street",
				"City": "Monroe",
				"State": "WI",
				"ZIP": "53566",
				"County": "Green",
				"Country": "USA"
			},
			"PhoneNumber": {
				"Home": null,
				"Business": null,
				"Mobile": null
			},
			"EmailAddresses": [],
			"Type": null,
			"RelationToPatient": "Father",
			"Employer": {
				"Name": "Accelerator Labs",
				"Address": {
					"StreetAddress": "1456 Old Sauk Road",
					"City": "Madison",
					"State": "WI",
					"ZIP": "53719",
					"County": "Dane",
					"Country": "USA"
				},
				"PhoneNumber": "+18083451121"
			}
		},
		"Insurances": [
			{
				"Plan": {
					"ID": "31572",
					"IDType": "Payor ID",
					"Name": "HMO Deductable Plan",
					"Type": null
				},
				"MemberNumber": null,
				"Company": {
					"ID": "60054",
					"IDType": null,
					"Name": "aetna (60054 0131)",
					"Address": {
						"StreetAddress": "PO Box 14080",
						"City": "Lexington",
						"State": "KY",
						"ZIP": "40512-4079",
						"County": "Fayette",
						"Country": "US"
					},
					"PhoneNumber": "+18089541123"
				},
				"GroupNumber": "847025-024-0009",
				"GroupName": "Accelerator Labs",
				"EffectiveDate": "2015-01-01",
				"ExpirationDate": "2020-12-31",
				"PolicyNumber": "9140860055",
				"AgreementType": null,
				"CoverageType": null,
				"Insured": {
					"Identifiers": [],
					"LastName": null,
					"MiddleName": null,
					"FirstName": null,
					"SSN": null,
					"Relationship": null,
					"DOB": null,
					"Sex": null,
					"Address": {
						"StreetAddress": null,
						"City": null,
						"State": null,
						"ZIP": null,
						"County": null,
						"Country": null
					}
				}
			}
		]
	}
}'

Patient Update

Any time an existing patient has demographics or other patient-level information updated, a message similar to the following should be sent:

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token from auth process}}" \
-d '{
    "Meta": {
		"DataModel": "PatientAdmin",
		"EventType": "PatientUpdate",
		"EventDateTime": "2019-10-24T22:04:47.915Z",
		"Test": true,
		"Destinations": [
			{
				"ID": "377a1892-378a-4475-ae27-87f17648770e",
				"Name": "RLS Destination"
			}
		]
	},
	"Patient": {
		"Identifiers": [
			{
				"ID": "{{some random prefix here such as your org OID}}.1",
				"IDType": "MR"
			},
			{
				"ID": "e167267c-16c9-4fe3-96ae-9cff5703e90a",
				"IDType": "EHRID"
			},
			{
				"ID": "a1d4ee8aba494ca",
				"IDType": "NIST"
			}
		],
		"Demographics": {
			"FirstName": "Timothy",
			"MiddleName": "Paul",
			"LastName": "Bixby",
			"DOB": "2008-01-06",
			"SSN": "101-01-0001",
			"Sex": "Male",
			"Race": "White",
			"IsHispanic": null,
			"MaritalStatus": "Married",
			"IsDeceased": null,
			"DeathDateTime": null,
			"PhoneNumber": {
				"Home": "+18088675301",
				"Office": null,
				"Mobile": null
			},
			"EmailAddresses": [],
			"Language": "en",
			"Citizenship": [],
			"Address": {
				"StreetAddress": "4435 Victoria Ln",
				"City": "Madison",
				"State": "WI",
				"ZIP": "53719",
				"County": "Dane",
				"Country": "US"
			}
		},
		"Notes": [],
		"Contacts": [
			{
				"FirstName": "Barbara",
				"MiddleName": null,
				"LastName": "Bixby",
				"Address": {
					"StreetAddress": "4762 Hickory Street",
					"City": "Monroe",
					"State": "WI",
					"ZIP": "53566",
					"County": "Green",
					"Country": "US"
				},
				"PhoneNumber": {
					"Home": "+18088675303",
					"Office": "+17077543758",
					"Mobile": "+19189368865"
				},
				"RelationToPatient": "Mother",
				"EmailAddresses": [
					"[email protected]"
				],
				"Roles": [
					"Emergency Contact"
				]
			}
		],
		"Diagnoses": [
			{
				"Code": "R07.0",
				"Codeset": "ICD-10",
				"Name": "Pain in throat",
				"Type": null,
				"DocumentedDateTime": null
			}
		],
		"Allergies": [
			{
				"Code": "7982",
				"Codeset": "RxNorm",
				"Name": "Penicillin",
				"Type": {
					"Code": null,
					"Codeset": null,
					"Name": null
				},
				"OnsetDateTime": null,
				"Reaction": [
					{
						"Code": "28926001",
						"Codeset": "SNOMED CT",
						"Name": "Rash"
					},
					{
						"Code": "247472004",
						"Codeset": "SNOMED CT",
						"Name": "Hives"
					}
				],
				"Severity": {
					"Code": null,
					"Codeset": null,
					"Name": null
				},
				"Status": null
			}
		],
		"PCP": {
			"NPI": "4356789876",
			"ID": "4356789876",
			"IDType": "NPI",
			"FirstName": "Pat",
			"LastName": "Granite",
			"Credentials": [
				"MD"
			],
			"Address": {
				"StreetAddress": "123 Main St.",
				"City": "Madison",
				"State": "WI",
				"ZIP": "53703",
				"County": "Dane",
				"Country": "USA"
			},
			"EmailAddresses": [],
			"PhoneNumber": {
				"Office": "+16085551234"
			},
			"Location": {
				"Type": null,
				"Facility": null,
				"Department": null,
				"Room": null
			}
		},
		"Insurances": [
			{
				"Plan": {
					"ID": "31572",
					"IDType": "Payor ID",
					"Name": "HMO Deductable Plan",
					"Type": null
				},
				"MemberNumber": null,
				"Company": {
					"ID": "60054",
					"IDType": null,
					"Name": "aetna (60054 0131)",
					"Address": {
						"StreetAddress": "PO Box 14080",
						"City": "Lexington",
						"State": "KY",
						"ZIP": "40512-4079",
						"County": "Fayette",
						"Country": "US"
					},
					"PhoneNumber": "+18089541123"
				},
				"GroupNumber": "847025-024-0009",
				"GroupName": "Accelerator Labs",
				"EffectiveDate": "2015-01-01",
				"ExpirationDate": "2020-12-31",
				"PolicyNumber": "9140860055",
				"AgreementType": null,
				"CoverageType": null,
				"Insured": {
					"Identifiers": [],
					"LastName": null,
					"MiddleName": null,
					"FirstName": null,
					"SSN": null,
					"Relationship": null,
					"DOB": null,
					"Sex": null,
					"Address": {
						"StreetAddress": null,
						"City": null,
						"State": null,
						"ZIP": null,
						"County": null,
						"Country": null
					}
				}
			}
		],
		"Guarantor": {
			"Number": "10001910",
			"FirstName": "Kent",
			"MiddleName": null,
			"LastName": "Bixby",
			"SSN": null,
			"DOB": null,
			"Sex": null,
			"Spouse": {
				"FirstName": "Barbara",
				"LastName": "Bixby"
			},
			"Address": {
				"StreetAddress": "4762 Hickory Street",
				"City": "Monroe",
				"State": "WI",
				"ZIP": "53566",
				"County": "Green",
				"Country": "USA"
			},
			"PhoneNumber": {
				"Home": null,
				"Business": null,
				"Mobile": null
			},
			"EmailAddresses": [],
			"Type": null,
			"RelationToPatient": "Father",
			"Employer": {
				"Name": "Accelerator Labs",
				"Address": {
					"StreetAddress": "1456 Old Sauk Road",
					"City": "Madison",
					"State": "WI",
					"ZIP": "53719",
					"County": "Dane",
					"Country": "USA"
				},
				"PhoneNumber": "+18083451121"
			}
		}
	}
}'

Patient Merge

Any time a patient is combined with another patient, a message similar to the below should be sent. The previous identifiers will be retried and ano longer valid for this patient.

curl \
-X POST https://api.redoxengine.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{access token from auth process}}" \
-d '{
    "Meta": {
		"DataModel": "PatientAdmin",
		"EventType": "PatientMerge",
		"EventDateTime": "2019-10-24T22:04:47.915Z",
		"Test": true,
		"Destinations": [
			{
				"ID": "377a1892-378a-4475-ae27-87f17648770e",
				"Name": "RLS Destination"
			}
		]
	},
	"Patient": {
		"Identifiers": [
			{
				"ID": "{{some random prefix here such as your org OID}}.2",
				"IDType": "MR"
			},
			{
				"ID": "e167267c-16c9-4fe3-96ae-9cff5703e90a",
				"IDType": "EHRID"
			},
			{
				"ID": "a1d4ee8aba494ca",
				"IDType": "NIST"
			}
		],
		"PreviousIdentifiers": [
			{
				"ID": "{{some random prefix here such as your org OID}}.1",
				"IDType": "MR"
			}
		],
		"Demographics": {
			"FirstName": "Timothy",
			"MiddleName": "Paul",
			"LastName": "Bixby",
			"DOB": "2008-01-06",
			"SSN": "101-01-0001",
			"Sex": "Male",
			"Race": "White",
			"IsHispanic": null,
			"MaritalStatus": "Married",
			"IsDeceased": null,
			"DeathDateTime": null,
			"PhoneNumber": {
				"Home": "+18088675301",
				"Office": null,
				"Mobile": null
			},
			"EmailAddresses": [],
			"Language": "en",
			"Citizenship": [],
			"Address": {
				"StreetAddress": "4762 Hickory Street",
				"City": "Monroe",
				"State": "WI",
				"ZIP": "53566",
				"County": "Green",
				"Country": "US"
			}
		},
		"Notes": []
	}
}'

Handling Incoming Requests

The Redox Carequality Gateway is our recommended way of handling queries from the network at-large. However, it is by no means the only way to fulfill your organization’s duty to respond to queries on the network. Responding to Carequality queries directly requires that you enable an HTTP interface that can be communicated with as a Redox destination. This destination endpoint will need to handle and respond to queries that come in the form of both DocumentQuery, and DocumentGet data models.

DocumentQuery

DocumentQuery requests provide a query body that takes the following form:


{
  "Meta": {
    "DataModel": "Clinical Summary",
    "EventType": "DocumentQuery",
    "EventDateTime": "2020-10-15T16:29:16.723Z",
    "Test": true,
    "Destinations": [
        {
          "ID": "ef9e7448-7f65-4432-aa96-059647e9b357",
          "Name": "Patient Query Endpoint"
        }
    ],
    "FacilityCode": null
  },
  "Patient": {
    "Identifiers": [
        {
          "ID": "0000000001",
          "IDType": "MR"
        },
        {
          "ID": "e167267c-16c9-4fe3-96ae-9cff5703e90a",
          "IDType": "EHRID"
        },
        {
          "ID": "a1d4ee8aba494ca",
          "IDType": "NIST"
        }
    ]
  },
  "Location": {
    "Department": null
  },
  "Visit": {
    "ID": "1222335",
    "StartDateTime": null,
    "EndDateTime": null
  },
  "Document": {
    "StartDate": null,
    "EndDate": null,
    "Types": [
        {
          "Code": "34133-9",
          "Codeset": "LOINC",
          "Name": "Continuity of Care Document"
        }
    ]
  }
}

And expects a response in our DocumentQueryResponse data model. A DocumentQueryResponse should be in the same format as the example response below:


{
   "Meta": {
      "DataModel": "Clinical Summary",
      "EventType": "DocumentQueryResponse",
      "EventDateTime": "2020-10-15T16:29:16.723Z",
      "Test": true,
      "Source": {
         "ID": "7ce6f387-c33c-417d-8682-81e83628cbd9",
         "Name": "Redox Dev Tools"
      },
      "Destinations": [
         {
            "ID": "af394f14-b34a-464f-8d24-895f370af4c9",
            "Name": "Redox EMR"
         }
      ],
      "Message": {
         "ID": 5565
      },
      "Transmission": {
         "ID": 12414
      },
      "FacilityCode": null
   },
   "Patient": {
      "Identifiers": [
         {
            "ID": "0000000001",
            "IDType": "MR"
         },
         {
            "ID": "e167267c-16c9-4fe3-96ae-9cff5703e90a",
            "IDType": "EHRID"
         },
         {
            "ID": "a1d4ee8aba494ca",
            "IDType": "NIST"
         }
      ]
   },
   "Documents": [
      {
         "Location": {
            "Department": null
         },
         "Author": {
            "ID": "4356789876",
            "IDType": "NPI",
            "Type": null,
            "FirstName": "Pat",
            "LastName": "Granite",
            "Credentials": [
               "MD"
            ],
            "Address": {
               "StreetAddress": "123 Main St.",
               "City": "Madison",
               "State": "WI",
               "ZIP": "53703",
               "County": "Dane",
               "Country": "USA"
            },
            "EmailAddresses": [],
            "PhoneNumber": {
               "Office": "+16085551234"
            },
            "Location": {
               "Type": null,
               "Facility": null,
               "Department": null,
               "Room": null
            }
         },
         "Visit": {
            "ID": "12345678",
            "StartDateTime": null,
            "EndDateTime": null
         },
         "DateTime": "2020-10-15T16:29:17.555Z",
         "ID": "123",
         "Locale": "US",
         "Title": "Discharge Summary",
         "Type": {
            "Code": "18842-5",
            "Codeset": "http://hl7.org/fhir/ValueSet/c80-doc-typecodes",
            "Name": "Discharge summary"
         }
      }
   ]
}

DocumentGet

DocumentGet requests provide a query body that takes the following form:


{
  "Meta": {
    "DataModel": "Clinical Summary",
    "EventType": "DocumentGet",
    "EventDateTime": "2020-10-15T16:29:16.723Z",
    "Test": true,
    "Destinations": [
        {
          "ID": "af394f14-b34a-464f-8d24-895f370af4c9",
          "Name": "Redox EMR"
        }
    ],
    "FacilityCode": null
  },
  "Document": {
    "ID": "2.16.840.1.113883.3.6147^1234"
  }
}

And expects a response in our DocumentGetResponse data model. A DocumentGetResponse should be in the same format as the example response below:


{
  "Meta": {
    "DataModel": "Clinical Summary",
    "EventType": "DocumentGetResponse",
    "EventDateTime": "2020-10-15T16:29:16.723Z",
    "Test": true,
    "Source": {
        "ID": "7ce6f387-c33c-417d-8682-81e83628cbd9",
        "Name": "Redox Dev Tools"
    },
    "Destinations": [
        {
          "ID": "af394f14-b34a-464f-8d24-895f370af4c9",
          "Name": "Redox EMR"
        }
    ],
    "Message": {
        "ID": 5565
    },
    "Transmission": {
        "ID": 12414
    },
    "FacilityCode": null
  },
  "Document": {
    "ID": "123"
  },
  "FileType": "text/xml",
  "Data": ""
}

Scalability and Availability

The Carequality network works by allowing querying parties to reach a vast number of organizations. The consequence of this is that every node on the network handling these queries is subject to a significant amount of traffic. The Redox Carequality Gateway was built with high traffic and high availability from the start, and for that reason using the gateway is our recommended solution for responding to queries.