ESMD FHIR Implementation Guide
1.0.0 - esmd
ESMD FHIR Implementation Guide - Local Development build (v1.0.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
The Generate Presigned URL API is designed to allow secure and controlled access to upload files to the esMD system. This API generates a presigned URL that enables authorized users to upload clinical documents to the esMD cloud storage without requiring direct access to the storage system. The API supports file metadata validation, secure URL generation, and integrates with the esMD FHIR framework to ensure compliance with healthcare data standards.
This document outlines the API endpoints, request structure, response format, and error handling mechanisms required for successful integration.
api/esmdf/ext/v1/fhir/DocumentReference/$generate-presigned-urlhttps://val.cpiapigateway.cms.gov/api/esmdf/ext/v1/fhir/DocumentReference/$generate-presigned-urlhttps://cpiapigateway.cms.gov/api/esmdf/ext/v1/fhir/DocumentReference/$generate-presigned-url| Header | Description | Required | Data Type | Comments |
| Accept | Accept must be application/fhir+json | Yes | String | application/fhir+json |
| content-type | content-type must be application/fhir+json | Yes | String | application/fhir+json |
| Authorization | Authentication token from Auth API | Yes | String | Example: Bearer {token} |
| Parameter | Description | Required | Type | Example |
| resourceType | Identifies the resource type as Parameters | Yes | String | Parameters |
| id | Unique identifier for this Parameters request | Yes | String | Example-generate-presigned-url |
| parameter | Contains request details in nested parts | Yes | ||
| organizationid | Sender’s Object Identifier (OID) | Yes | string | urn:oid:2.16.840.1.113883.4.1.1.1234 |
| fileinfo | Metadata about the file (nested elements below) | Yes | ||
| filename | The name of the file | Yes | String | real_payload_1mb_1.xml |
| content-type | Media Type of the document | Yes | String | application/xml |
| content-md5 | MD5 hash of file content, base64-encoded | Yes | String | 6npmAXaJZY3vMZcs+6O61A== |
| filesize | Size of the file and size should be in MB | Yes | String | 20 |
Example Request:
{
"resourceType": "Parameters",
"id": "6ce2bb15-cc4e-4d2d-979c-fd4df85d26f9",
"parameter": [
{
"name": "organizationid",
"valueString": "urn:oid:123.456.657.126"
},
{
"name": "fileinfo",
"part": [
{
"name": "filename",
"valueString": "6ce2bb15-cc4e-4d2d-979c-fd4df85d26f9_1.xml"
},
{
"name": "content-md5",
"valueString": "JvTXRKcDNLs082LvjEDaaw=="
},
{
"name": "filesize",
"valueString": "0.5"
},
{
"name": "mimetype",
"valueString": "application/xml"
}
]
}
]
}
Successful Response Information
{
"resourceType": "Parameters",
"id": "6ce2bb15-cc4e-4d2d-979c-fd4df85d26f9",
"parameter": [
{
"name": "presignedUrls",
"part": [
{
"name": "file",
"part": [
{
"name": "filename",
"valueString": "6ce2bb15-cc4e-4d2d-979c-fd4df85d26f9_1.xml"
},
{
"name": "uploadUrl",
"valueUrl": "https://esmdcloud2-uat.cms.hhs.gov:9013/6ce2bb15-cc4e-4d2d-979c-fd4df85d26f9/6ce2bb15-cc4e-4d2d-979c-fd4df85d26f9_1.xml?X-Amz-Security-Token=IQoJb3JpZ2luX2VjEOj%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIB1D1B7I9jL6A4mPrINgSqKgzeUPwS0DLxUFwkco88h0AiEAkQzVIeA%2BJHlxxmfGgm7rVgAZPSfFaN4r5Ffy6dpf0GgqxgUIwf%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARABGgw4MTgzNDU1MDMwMjkiDOOS1ChZE6ZaMRd4gSqaBb4gUJCa5UXxpXxZnKR%2BxL1hZhyfmAsOfMmk6XMXdaIq825WGSe4nH5GcO3YNZ1AeIIXW%2F7Dq%2BZWqjLTmFdeKTv3EBmMRfxA8r3BKE7DIQ9I4JVZJ9sgpGmiU%2BQymF2z%2FQ9NaMzzGe1uEKPM8nb7CJJ0T5GLPpDOE7dBTNqfTSnn31LIBTrTVzlRJ7z5%2Bg5ivqzQjkMIeNuxl%2F4GlSYieXkYpV%2BTTa1nVL1GFfALKPItlI10JkdBTkMzF%2Bp3w6In9JXzA7%2BtGgEEmxdugEfinAoyfPudDYR7yNIzAMqx9YHQsDBYZM%2BmANxavunkP9huEh5azXVJv7hGPQ5imK%2FavVvkfDII0XOZJQubWMcdiv9oYTvWe1AofItGuOYbXOVEjs1SP6EeWHAMoOMkkYseD0VAql2%2BEFgK%2FqkMNytCvNzCIAOmxmAwqYFLBg0DpqCLM8%2BuRsIjOI%2FHnWNnCi9uI%2FBWsn8390%2FY7zUGuIg2GreTUCm9HtmB3vg04S1AovkZHkyOk9Pwr1fEXoOSRqn2HoYQ18WdafXO1RDMcCiXiaaopRRVt8XA4YmuKQipHpe%2BFoDjrd1BvvBeVcIfoUl%2BbIXFL0Gt4Xn7WDoaiLdCU5ezMvhlYmF%2FXv0D2lctyZwWBmYozR59cvEEXmgwisGb96Vd24Ce6xhgYUoIiQJVNEC1OiZHWTUepHeAodM7z5CImJm24x2x55nU7Tmm8J8Zc%2FIVL10N%2FBYVL7kewBwGEqTeSy3D4VUc93SZ%2Fon7zCnm9e%2BZbhIq%2FUesFpOz%2BkkmMV8308r%2FBBdKQB%2BejO9ZSzdn5U76CWvJOLf8tUSiPkWLnPbvxXH3FxumTzewb2DDMAQMWegNvE2yrzzGlFQ2m%2FzF2fSrEwlIhm4pHDCDo6HCBjqxAbZnmyQ2Xa2iqLkCLC8V6tSB%2B449A5OuXMVllyN%2B5IJWKx0LnKGAwfaQXwX2e3vfyaa71aZMQT%2BsBJFSOf3db%2FResNtMNQBiPv3T%2BlhB4NHUw6QvDOGaDPxQJjy8uIuko6bNjwtV3bdv1u%2BzSc1HClJfwJECm9zoz2NUaliopKvC5rsTPZgPkMsrnlm5X9cbcteOw2pezw6kNN9iW84WHD1s%2BHV4qLFKNMQ8Px6MXo9F%2FA%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20250610T155129Z&X-Amz-SignedHeaders=content-md5%3Bhost&X-Amz-Expires=899&X-Amz-Credential=ASIA35CJRNE2SIENK3S3%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=cf5e5d1d5cc1ba87b442bb41a9e715c626716922b0e0573826c74df29410726c"
}
]
}
]
},
{
"name": "expiresIn",
"valueDuration": {
"value": 900,
"unit": "seconds",
"system": "http://unitsofmeasure.org",
"code": "s"
}
}
]
}
Failure Response Information
{
"resourceType": "OperationOutcome",
"meta": {
"profile": [
"https://terminology.esmduat.cms.gov:8099/fhir/StructureDefinition/Esmd-BundleSubmissionResponse"
]
},
"issue": [
{
"severity": "error",
"code": "processing",
"details": {
"coding": [
{
"system": "https://terminology.esmduat.cms.gov:8099/fhir/CodeSystem/Esmd-CS-ErrorOrWarningCodes",
"code": "DUPLICATE_UNIQUE_ID",
"display": "Duplicate Unique ID submitted in Parameters resource testpresigneduniqueid-test1; the submission is rejected."
}
]
}
}
]
}
| Parameter | Description | Type | Example |
| resourceType | Identifies the resource type as Parameters | String | Parameters |
| id | Unique identifier for this Parameters request | String | Example-generate-presigned-url |
| presignedUrls | Contains presigned URL data for each file | Array of Objects | |
| file | Metadata and upload URL for each file | Array of Objects | |
| filename | Name of the file | String | real_payload_1mb_1.xml |
| uploadUrl | Secure presigned URL for file upload | String | https://esmdcloud-dev.cms.hhs.gov:9013/upload/... |
| expiresIn | Expiration duration for presigned URLs | Object | |
| value | Duration value in seconds | String | 900 |
| unit | Unit for expiration duration | String | seconds |
| system | Unit system URL | String | http://unitsofmeasure.org |
| code | Code for expiration duration unit | String | s |
This document provides detailed instructions for Health Information Handlers (HIHs) on securely uploading clinical XML documents to esMD's FHIR Storage (S3) using presigned URLs. Presigned URLs provide a secure, time-limited method for uploading files without exposing credentials. HIHs generate these URLs using esMD's FHIR API and must complete the upload before expiration.
Step 1: Obtain Presigned URLs HIHs must first generate a presigned URL by making a request to the esMD FHIR API (See Step 2 in the documentation).
Step 2: Upload Clinical Documents Using Presigned URLs Once presigned URLs are obtained, HIHs should use them to upload clinical XML documents securely.
Step 3: Verify Upload & Handle Errors
HTTP Method: POST
URL: Use the presigned URL provided by esMD in response to the generate-presigned-url request.
Required Request Headers
| Header | Description |
| Authorization | Bearer <token> (Generated in previous steps) |
| Content-Type | application/xml (Indicates clinical XML file) |
| Content-Length | <Size of the request body in bytes> |
| Accept | */* |
| Content-MD5 | <MD5 hash of file content > |
Request Body
Example Presigned URL Request
https://esmdcloud-dev.cms.hhs.gov:9013/upload/testpresigneduniqueid-test1/testpresigneduniqueid-test1_1.xml?X-Amz-Security-Token=<token>&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20250210T215944Z&X-Amz-SignedHeaders=content-md5%3Bhost&X-Amz-Expires=899&X-Amz-Credential=ASIA35CJRNE2ZRNXVKXJ/20250210/us-east-1/s3/aws4_request&X-Amz-Signature=<signature>
Presigned URL Query Parameters
| Parameter | Description |
| X-Amz-Security-Token | Temporary security token for authentication |
| X-Amz-Algorithm | Signing algorithm used (AWS4-HMAC-SHA256) |
| X-Amz-Date | Timestamp to prevent replay attacks (YYYYMMDD'T'HHMMSS'Z) |
| X-Amz-SignedHeaders | Headers included in the request signature (e.g., content-md5;host) |
| X-Amz-Expires | Time in seconds before the presigned URL expires |
| X-Amz-Credential | AWS access key, request date, region, and service used in the signature |
| X-Amz-Signature | Digital signature to authorize the request |
Example Upload Request
POST <Presigned URL received in Step 2>
Authorization: Bearer <token>
Content-Type: application/xml
Content-MD5:JvTXRKcDNLs082LvjEDaaw==
[Content of the clinical XML document]
Success Response Upon successful upload, esMD returns:
{
"status": "SUCCESS",
"message": "FILE UPLOADED SUCCESSFULLY",
"filename": "6ce2bb15-cc4e-4d2d-979c-fd4df85d26f8_1.xml",
"s3uri": "s3://uat-esmd-qurantine/6ce2bb15-cc4e-4d2d-979c-fd4df85d26f8/6ce2bb15-cc4e-4d2d-979c-fd4df85d26f8_1.xml"
}
Failure Response If the upload fails due to an expired URL, esMD returns:
{
"Error": {
"Code": "AccessDenied",
"Message": "Request has expired",
"X-Amz-Expires": "900",
"Expires": "2025-02-10T22:14:44Z",
"ServerTime": "2025-02-11T20:21:01Z",
"RequestId": "FBAZC9P4KJ9PHMSF",
"HostId": "m6A6+q0AWptHSdS/qNqHIev1SfTUUML9E59A8b3W6cRUIcQM6nXXqLB+gTApG7M35AnAKwDZt/dHwJL1VsAMwQ=="
}
}
| Consideration | Details |
| File Integrity | Ensure the MD5 hash of the file matches the value provided during presigned URL generation to avoid corruption. |
| URL Expiration | HIHs must complete the upload before expiration. If expired, request a new presigned URL. |
| Multiple Files | All transaction bundle-related files must be uploaded before submitting the bundle. |
| Secure Transmission | Always use HTTPS when accessing presigned URLs. |
| Issue | Solution |
| 401 Unauthorized | Verify the Bearer token is correct and not expired. |
| 403 Forbidden | Check if the presigned URL is expired or query parameters were modified. |
| Expired URL | If X-Amz-Expires has elapsed, request a new presigned URL from esMD. |
| Type | Code | Status | Resolution |
| Success | 200 | OK | Request processed successfully. No action needed. |
| Error | 400 | Bad Request | Missing or invalid headers or parameters. Check request headers or parameters and resubmit. |
| Error | 401 | Unauthorized | Invalid client ID or client secret. Correct the details and resubmit. |
| Error | 403 | Forbidden | Insufficient permissions or server configuration issues. Contact esMD Support. |
| Error | 404 | Not Found | Invalid URL. Correct the endpoint URL and resubmit. |
| Error | 422 | Unprocessable Entity | Metadata failure. Update metadata and resubmit. |
| Error | 500 | Internal Server Error | Unexpected server error. Contact esMD Support. |
| Error | 502 | Bad Gateway | Contact esMD Support. |
| Error | 503 | Service Unavailable | Contact esMD Support. |