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

Generate Presigned URL API

Overview

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 URL Details

  • Operation Name: api/esmdf/ext/v1/fhir/DocumentReference/$generate-presigned-url
  • Method: POST
  • Authentication Required: Yes

Endpoints:

  • UAT: https://val.cpiapigateway.cms.gov/api/esmdf/ext/v1/fhir/DocumentReference/$generate-presigned-url
  • PROD: https://cpiapigateway.cms.gov/api/esmdf/ext/v1/fhir/DocumentReference/$generate-presigned-url

Request Headers

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}

Parameters Resource Elements

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

Parameters Resource Structure

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."
                    }
                ]
            }
        }
    ]
}

Response Elements

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

Upload Clinical Documents to esMD FHIR Storage Documentation

Overview

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.

Upload Process

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

  • HIHs must ensure successful upload by verifying responses.
  • If the upload fails due to expiration or authentication errors, a new presigned URL must be requested.

API Details

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

  • The request body should contain the clinical XML document data being uploaded.

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]

Example Responses

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=="
    }
}

Important Considerations

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.

Troubleshooting Guide

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.

Generate Presigned URL Response Codes

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.